diff options
Diffstat (limited to 'src')
585 files changed, 15046 insertions, 20638 deletions
diff --git a/src/auditor/.gitignore b/src/auditor/.gitignore index e7812f058..a0bae7d8b 100644 --- a/src/auditor/.gitignore +++ b/src/auditor/.gitignore @@ -29,3 +29,4 @@ generate-kyc-basedb.conf.edited generate-auditor-basedb.conf.edited wallet.wdb libeufin-bank.pid +taler-helper-auditor-transfer diff --git a/src/auditor/Makefile.am b/src/auditor/Makefile.am index ab25b30f3..99a10fcd2 100644 --- a/src/auditor/Makefile.am +++ b/src/auditor/Makefile.am @@ -23,6 +23,7 @@ bin_PROGRAMS = \ taler-helper-auditor-deposits \ taler-helper-auditor-purses \ taler-helper-auditor-reserves \ + taler-helper-auditor-transfer \ taler-helper-auditor-wire-credit \ taler-helper-auditor-wire-debit @@ -141,7 +142,19 @@ taler_helper_auditor_reserves_LDADD = \ -lgnunetutil \ $(XLIB) - +taler_helper_auditor_transfer_SOURCES = \ + taler-helper-auditor-transfer.c +taler_helper_auditor_transfer_LDADD = \ + $(LIBGCRYPT_LIBS) \ + $(top_builddir)/src/util/libtalerutil.la \ + $(top_builddir)/src/json/libtalerjson.la \ + $(top_builddir)/src/exchangedb/libtalerexchangedb.la \ + $(top_builddir)/src/auditordb/libtalerauditordb.la \ + libauditorreport.la \ + -ljansson \ + -lgnunetjson \ + -lgnunetutil \ + $(XLIB) taler_helper_auditor_wire_credit_SOURCES = \ taler-helper-auditor-wire-credit.c @@ -179,79 +192,37 @@ taler_helper_auditor_wire_debit_LDADD = \ taler_auditor_httpd_SOURCES = \ taler-auditor-httpd.c taler-auditor-httpd.h \ + taler-auditor-httpd_spa.c taler-auditor-httpd_spa.h \ taler-auditor-httpd_deposit-confirmation.c taler-auditor-httpd_deposit-confirmation.h \ taler-auditor-httpd_deposit-confirmation-get.c taler-auditor-httpd_deposit-confirmation-get.h \ - taler-auditor-httpd_deposit-confirmation-del.c taler-auditor-httpd_deposit-confirmation-del.h \ - taler-auditor-httpd_deposit-confirmation-upd.c taler-auditor-httpd_deposit-confirmation-upd.h \ taler-auditor-httpd_amount-arithmetic-inconsistency-get.c taler-auditor-httpd_amount-arithmetic-inconsistency-get.h \ taler-auditor-httpd_coin-inconsistency-get.c taler-auditor-httpd_coin-inconsistency-get.h \ taler-auditor-httpd_row-inconsistency-get.c taler-auditor-httpd_row-inconsistency-get.h \ - taler-auditor-httpd_amount-arithmetic-inconsistency-del.c taler-auditor-httpd_amount-arithmetic-inconsistency-del.h \ - taler-auditor-httpd_coin-inconsistency-del.c taler-auditor-httpd_coin-inconsistency-del.h \ - taler-auditor-httpd_row-inconsistency-del.c taler-auditor-httpd_row-inconsistency-del.h \ - taler-auditor-httpd_amount-arithmetic-inconsistency-upd.c taler-auditor-httpd_amount-arithmetic-inconsistency-upd.h \ taler-auditor-httpd_emergency-get.c taler-auditor-httpd_emergency-get.h \ - taler-auditor-httpd_emergency-del.c taler-auditor-httpd_emergency-del.h \ taler-auditor-httpd_emergency-by-count-get.c taler-auditor-httpd_emergency-by-count-get.h \ - taler-auditor-httpd_emergency-by-count-del.c taler-auditor-httpd_emergency-by-count-del.h \ taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-get.c taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-get.h \ - taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-del.c taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-del.h \ taler-auditor-httpd_purse-not-closed-inconsistencies-get.c taler-auditor-httpd_purse-not-closed-inconsistencies-get.h \ - taler-auditor-httpd_purse-not-closed-inconsistencies-del.c taler-auditor-httpd_purse-not-closed-inconsistencies-del.h \ taler-auditor-httpd_reserve-balance-insufficient-inconsistency-get.c taler-auditor-httpd_reserve-balance-insufficient-inconsistency-get.h \ taler-auditor-httpd_patch_generic_suppressed.c taler-auditor-httpd_patch_generic_suppressed.h \ - taler-auditor-httpd_reserve-balance-insufficient-inconsistency-del.c taler-auditor-httpd_reserve-balance-insufficient-inconsistency-del.h \ + taler-auditor-httpd_delete_generic.c taler-auditor-httpd_delete_generic.h \ taler-auditor-httpd_bad-sig-losses-get.c taler-auditor-httpd_bad-sig-losses-get.h \ - taler-auditor-httpd_bad-sig-losses-del.c taler-auditor-httpd_bad-sig-losses-del.h \ - taler-auditor-httpd_bad-sig-losses-upd.c taler-auditor-httpd_bad-sig-losses-upd.h \ taler-auditor-httpd_closure-lags-get.c taler-auditor-httpd_closure-lags-get.h \ - taler-auditor-httpd_closure-lags-del.c taler-auditor-httpd_closure-lags-del.h \ taler-auditor-httpd_progress-get.c taler-auditor-httpd_progress-get.h \ taler-auditor-httpd_refreshes-hanging-get.c taler-auditor-httpd_refreshes-hanging-get.h \ - taler-auditor-httpd_refreshes-hanging-del.c taler-auditor-httpd_refreshes-hanging-del.h \ - taler-auditor-httpd_emergency-by-count-upd.c taler-auditor-httpd_emergency-by-count-upd.h \ - taler-auditor-httpd_row-inconsistency-upd.c taler-auditor-httpd_row-inconsistency-upd.h \ - taler-auditor-httpd_purse-not-closed-inconsistencies-upd.c taler-auditor-httpd_purse-not-closed-inconsistencies-upd.h \ - taler-auditor-httpd_reserve-balance-insufficient-inconsistency-upd.c taler-auditor-httpd_reserve-balance-insufficient-inconsistency-upd.h \ - taler-auditor-httpd_coin-inconsistency-upd.c taler-auditor-httpd_coin-inconsistency-upd.h \ - taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-upd.c taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-upd.h \ - taler-auditor-httpd_refreshes-hanging-upd.c taler-auditor-httpd_refreshes-hanging-upd.h \ - taler-auditor-httpd_emergency-upd.c taler-auditor-httpd_emergency-upd.h \ - taler-auditor-httpd_closure-lags-upd.c taler-auditor-httpd_closure-lags-upd.h \ - taler-auditor-httpd_reserve-in-inconsistency-del.c taler-auditor-httpd_reserve-in-inconsistency-del.h \ taler-auditor-httpd_reserve-in-inconsistency-get.c taler-auditor-httpd_reserve-in-inconsistency-get.h \ - taler-auditor-httpd_reserve-in-inconsistency-upd.c taler-auditor-httpd_reserve-in-inconsistency-upd.h \ - taler-auditor-httpd_reserve-not-closed-inconsistency-del.c taler-auditor-httpd_reserve-not-closed-inconsistency-del.h \ taler-auditor-httpd_reserve-not-closed-inconsistency-get.c taler-auditor-httpd_reserve-not-closed-inconsistency-get.h \ - taler-auditor-httpd_reserve-not-closed-inconsistency-upd.c taler-auditor-httpd_reserve-not-closed-inconsistency-upd.h \ - taler-auditor-httpd_denominations-without-sigs-del.c taler-auditor-httpd_denominations-without-sigs-del.h \ taler-auditor-httpd_denominations-without-sigs-get.c taler-auditor-httpd_denominations-without-sigs-get.h \ - taler-auditor-httpd_denominations-without-sigs-upd.c taler-auditor-httpd_denominations-without-sigs-upd.h \ - taler-auditor-httpd_misattribution-in-inconsistency-del.c taler-auditor-httpd_misattribution-in-inconsistency-del.h \ taler-auditor-httpd_misattribution-in-inconsistency-get.c taler-auditor-httpd_misattribution-in-inconsistency-get.h \ - taler-auditor-httpd_misattribution-in-inconsistency-upd.c taler-auditor-httpd_misattribution-in-inconsistency-upd.h \ taler-auditor-httpd_reserves-get.c taler-auditor-httpd_reserves-get.h \ taler-auditor-httpd_purses-get.c taler-auditor-httpd_purses-get.h \ taler-auditor-httpd_historic-denomination-revenue-get.c taler-auditor-httpd_historic-denomination-revenue-get.h \ - taler-auditor-httpd_denomination-pending-del.c taler-auditor-httpd_denomination-pending-del.h \ taler-auditor-httpd_denomination-pending-get.c taler-auditor-httpd_denomination-pending-get.h \ - taler-auditor-httpd_denomination-pending-upd.c taler-auditor-httpd_denomination-pending-upd.h \ taler-auditor-httpd_historic-reserve-summary-get.c taler-auditor-httpd_historic-reserve-summary-get.h \ - taler-auditor-httpd_wire-format-inconsistency-del.c taler-auditor-httpd_wire-format-inconsistency-del.h \ taler-auditor-httpd_wire-format-inconsistency-get.c taler-auditor-httpd_wire-format-inconsistency-get.h \ - taler-auditor-httpd_wire-format-inconsistency-upd.c taler-auditor-httpd_wire-format-inconsistency-upd.h \ - taler-auditor-httpd_wire-out-inconsistency-del.c taler-auditor-httpd_wire-out-inconsistency-del.h \ taler-auditor-httpd_wire-out-inconsistency-get.c taler-auditor-httpd_wire-out-inconsistency-get.h \ - taler-auditor-httpd_wire-out-inconsistency-upd.c taler-auditor-httpd_wire-out-inconsistency-upd.h \ - taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-del.c taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-del.h \ taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-get.c taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-get.h \ - taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-upd.c taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-upd.h \ - taler-auditor-httpd_row-minor-inconsistencies-del.c taler-auditor-httpd_row-minor-inconsistencies-del.h \ taler-auditor-httpd_row-minor-inconsistencies-get.c taler-auditor-httpd_row-minor-inconsistencies-get.h \ - taler-auditor-httpd_row-minor-inconsistencies-upd.c taler-auditor-httpd_row-minor-inconsistencies-upd.h \ - taler-auditor-httpd_fee-time-inconsistency-del.c taler-auditor-httpd_fee-time-inconsistency-del.h \ taler-auditor-httpd_fee-time-inconsistency-get.c taler-auditor-httpd_fee-time-inconsistency-get.h \ - taler-auditor-httpd_fee-time-inconsistency-upd.c taler-auditor-httpd_fee-time-inconsistency-upd.h \ taler-auditor-httpd_balances-get.c taler-auditor-httpd_balances-get.h \ taler-auditor-httpd_mhd.c taler-auditor-httpd_mhd.h taler_auditor_httpd_LDADD = \ @@ -291,7 +262,11 @@ check_SCRIPTS = \ test-revocation.sh \ test-sync.sh -# TESTS = $(check_SCRIPTS) +TESTS = \ + test-revocation.sh \ + test-sync.sh +# test-auditor.sh + EXTRA_DIST = \ taler-auditor.in \ diff --git a/src/auditor/auditor.conf b/src/auditor/auditor.conf index 3c04d196f..9f55308b2 100644 --- a/src/auditor/auditor.conf +++ b/src/auditor/auditor.conf @@ -26,7 +26,7 @@ SERVE = tcp # Unix domain socket to listen on, # only effective with "SERVE = unix" -UNIXPATH = ${TALER_RUNTIME_DIR}exchange.http +UNIXPATH = ${TALER_RUNTIME_DIR}/auditor-httpd/auditor-http.sock UNIXPATH_MODE = 660 # HTTP port the auditor listens to diff --git a/src/auditor/batch.conf b/src/auditor/batch.conf index 2de9bbb32..3b6402e77 100644 --- a/src/auditor/batch.conf +++ b/src/auditor/batch.conf @@ -118,7 +118,7 @@ HONOR_default = YES PAYTO_URI = payto://x-taler-bank/localhost/42 [exchange-accountcredentials-1] -PASSWORD = x +PASSWORD = password USERNAME = exchange WIRE_GATEWAY_AUTH_METHOD = basic WIRE_GATEWAY_URL = http://localhost:8082/accounts/exchange/taler-wire-gateway/ diff --git a/src/auditor/generate-auditor-basedb.conf b/src/auditor/generate-auditor-basedb.conf index cbd8b1cd4..cdfffdbb0 100644 --- a/src/auditor/generate-auditor-basedb.conf +++ b/src/auditor/generate-auditor-basedb.conf @@ -36,6 +36,7 @@ WIRE_TYPE = iban IBAN_PAYTO_BIC = SANDBOXX SERVE = tcp PORT = 8082 +PWD_HASH_CONFIG = { "cost": 4 } [libeufin-bankdb-postgres] CONFIG = postgresql:///auditor-basedb @@ -47,7 +48,7 @@ IDLE_RESERVE_EXPIRATION_TIME = 4 weeks LEGAL_RESERVE_EXPIRATION_TIME = 4 weeks [exchange-account-1] -PAYTO_URI = payto://iban/SANDBOXX/DE989651?receiver-name=Exchange+Company +PAYTO_URI = payto://iban/DE989651?receiver-name=Exchange+Company ENABLE_DEBIT = YES ENABLE_CREDIT = YES @@ -55,26 +56,7 @@ ENABLE_CREDIT = YES WIRE_GATEWAY_URL = http://localhost:8082/accounts/exchange/taler-wire-gateway/ WIRE_GATEWAY_AUTH_METHOD = basic USERNAME = exchange -PASSWORD = x - -[exchange-account-2] -PAYTO_URI = "payto://x-taler-bank/localhost/2?receiver-name=2" -ENABLE_DEBIT = YES -ENABLE_CREDIT = YES - -[exchange-accountcredentials-2] -WIRE_GATEWAY_AUTH_METHOD = basic -USERNAME = exchange -PASSWORD = x -WIRE_GATEWAY_URL = "http://localhost:8082/accounts/exchange/taler-wire-gateway/" - -[admin-accountcredentials-2] -WIRE_GATEWAY_AUTH_METHOD = basic -# For now, fakebank still checks against the exchange account... -USERNAME = exchange -PASSWORD = x -WIRE_GATEWAY_URL = "http://localhost:8082/accounts/exchange/taler-wire-gateway/" - +PASSWORD = password [merchant] FORCE_AUDIT = YES @@ -108,6 +90,7 @@ REGISTRATION_BONUS = TESTKUDOS:100 SUGGESTED_WITHDRAWAL_EXCHANGE = http://localhost:8081/ SERVE = tcp PORT = 8082 +PWD_HASH_CONFIG = { "cost": 4 } [auditor] BASE_URL = http://localhost:8083/ diff --git a/src/auditor/generate-auditor-basedb.sh b/src/auditor/generate-auditor-basedb.sh index 82549de27..33831d06f 100755 --- a/src/auditor/generate-auditor-basedb.sh +++ b/src/auditor/generate-auditor-basedb.sh @@ -80,7 +80,7 @@ curl -H "Content-Type: application/json" -X POST -d '{"auth":{"method":"external echo " DONE" echo -n "Setting up merchant account ..." -FORTYTHREE="payto://iban/SANDBOXX/DE474361?receiver-name=Merchant43" +FORTYTHREE="payto://iban/DE474361?receiver-name=Merchant43" STATUS=$(curl -H "Content-Type: application/json" -X POST \ "${MERCHANT_URL}private/accounts" \ -d '{"payto_uri":"'"$FORTYTHREE"'"}' \ @@ -92,6 +92,16 @@ then fi echo " DONE" +echo -n "Setting up libeufin merchant account ..." +libeufin-bank create-account \ + --config="${CONF}" \ + --name="Merchant43" \ + --username="Merchant43" \ + --password="password" \ + --payto_uri="payto://iban/DE474361?receiver-name=Merchant43" + +echo " DONE" + # delete existing wallet database export WALLET_DB="wallet.wdb" rm -f "$WALLET_DB" diff --git a/src/auditor/report-lib.c b/src/auditor/report-lib.c index 6dd20d677..3ca2912a7 100644 --- a/src/auditor/report-lib.c +++ b/src/auditor/report-lib.c @@ -133,7 +133,7 @@ add_denomination ( enum GNUNET_DB_QueryStatus TALER_ARL_get_denomination_info_by_hash ( const struct TALER_DenominationHashP *dh, - const struct TALER_EXCHANGEDB_DenominationKeyInformation **issue) + const struct TALER_EXCHANGEDB_DenominationKeyInformation **issuep) { enum GNUNET_DB_QueryStatus qs; @@ -147,7 +147,7 @@ TALER_ARL_get_denomination_info_by_hash ( if (0 > qs) { GNUNET_break (0); - *issue = NULL; + *issuep = NULL; return qs; } } @@ -159,7 +159,7 @@ TALER_ARL_get_denomination_info_by_hash ( if (NULL != i) { /* cache hit */ - *issue = i; + *issuep = i; return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; } } @@ -191,7 +191,7 @@ TALER_ARL_get_denomination_info_by_hash ( if (NULL != i) { /* cache hit */ - *issue = i; + *issuep = i; return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; } } @@ -282,8 +282,7 @@ transact (TALER_ARL_Analysis analysis, else { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Processing failed (or no changes), rolling back transaction\n") - ; + "Processing failed; rolling back transaction\n"); TALER_ARL_adb->rollback (TALER_ARL_adb->cls); TALER_ARL_edb->rollback (TALER_ARL_edb->cls); } @@ -306,6 +305,8 @@ enum GNUNET_GenericReturnValue TALER_ARL_setup_sessions_and_run (TALER_ARL_Analysis ana, void *ana_cls) { + enum GNUNET_DB_QueryStatus qs; + if (GNUNET_SYSERR == TALER_ARL_edb->preflight (TALER_ARL_edb->cls)) { @@ -321,8 +322,14 @@ TALER_ARL_setup_sessions_and_run (TALER_ARL_Analysis ana, return GNUNET_SYSERR; } - if (0 > transact (ana, - ana_cls)) + for (unsigned int retries=0; retries<3; retries++) + { + qs = transact (ana, + ana_cls); + if (GNUNET_DB_STATUS_SOFT_ERROR != qs) + break; + } + if (qs < 0) return GNUNET_SYSERR; return GNUNET_OK; } diff --git a/src/auditor/report-lib.h b/src/auditor/report-lib.h index bf2d63740..369ac3ccf 100644 --- a/src/auditor/report-lib.h +++ b/src/auditor/report-lib.h @@ -135,14 +135,14 @@ extern struct GNUNET_TIME_Absolute start_time; * Obtain information about a @a denom_pub. * * @param dh hash of the denomination public key to look up - * @param[out] issue set to detailed information about @a denom_pub, NULL if not found, must + * @param[out] issuep set to detailed information about @a denom_pub, NULL if not found, must * NOT be freed by caller * @return transaction status code */ enum GNUNET_DB_QueryStatus TALER_ARL_get_denomination_info_by_hash ( const struct TALER_DenominationHashP *dh, - const struct TALER_EXCHANGEDB_DenominationKeyInformation **issue); + const struct TALER_EXCHANGEDB_DenominationKeyInformation **issuep); /** diff --git a/src/auditor/revoke-basedb.conf b/src/auditor/revoke-basedb.conf index 706f97347..c3bf83bf0 100644 --- a/src/auditor/revoke-basedb.conf +++ b/src/auditor/revoke-basedb.conf @@ -12,7 +12,7 @@ enable_credit = yes WIRE_GATEWAY_URL = "http://localhost:8082/accounts/exchange/taler-wire-gateway/" WIRE_GATEWAY_AUTH_METHOD = basic USERNAME = exchange -PASSWORD = x +PASSWORD = password [exchangedb] WIREFEE_BASE_DIR = ${PWD}/wirefees/ diff --git a/src/auditor/setup.sh b/src/auditor/setup.sh index bb17e92ae..41ddc3da2 100755 --- a/src/auditor/setup.sh +++ b/src/auditor/setup.sh @@ -70,16 +70,15 @@ function get_payto_uri() { # Stop libeufin-bank (if running) function stop_libeufin() { - echo -n "Stopping libeufin... " if [ -f "${MY_TMP_DIR:-/}/libeufin-bank.pid" ] then PID=$(cat "${MY_TMP_DIR}/libeufin-bank.pid" 2> /dev/null) - echo "Killing libeufin-bank $PID" + echo -n "Stopping libeufin $PID... " rm "${MY_TMP_DIR}/libeufin-bank.pid" kill "$PID" 2> /dev/null || true wait "$PID" || true + echo "DONE" fi - echo "DONE" } diff --git a/src/auditor/taler-auditor-dbinit.c b/src/auditor/taler-auditor-dbinit.c index 4cb46f470..9b4026ec6 100644 --- a/src/auditor/taler-auditor-dbinit.c +++ b/src/auditor/taler-auditor-dbinit.c @@ -139,10 +139,6 @@ main (int argc, }; enum GNUNET_GenericReturnValue ret; - if (GNUNET_OK != - GNUNET_STRINGS_get_utf8_args (argc, argv, - &argc, &argv)) - return EXIT_INVALIDARGUMENT; /* force linker to link against libtalerutil; if we do not do this, the linker may "optimize" libtalerutil away and skip #TALER_OS_init(), which we do need */ @@ -153,7 +149,6 @@ main (int argc, gettext_noop ("Initialize Taler auditor database"), options, &run, NULL); - GNUNET_free_nz ((void *) argv); if (GNUNET_SYSERR == ret) return EXIT_INVALIDARGUMENT; if (GNUNET_NO == ret) diff --git a/src/auditor/taler-auditor-httpd.c b/src/auditor/taler-auditor-httpd.c index bda028faf..3ae0176b5 100644 --- a/src/auditor/taler-auditor-httpd.c +++ b/src/auditor/taler-auditor-httpd.c @@ -30,109 +30,42 @@ #include "taler_mhd_lib.h" #include "taler_auditordb_lib.h" #include "taler_exchangedb_lib.h" +#include "taler-auditor-httpd_spa.h" #include "taler-auditor-httpd_deposit-confirmation.h" -#include "taler-auditor-httpd_deposit-confirmation-del.h" #include "taler-auditor-httpd_deposit-confirmation-get.h" #include "taler-auditor-httpd_amount-arithmetic-inconsistency-get.h" -#include "taler-auditor-httpd_amount-arithmetic-inconsistency-del.h" -#include "taler-auditor-httpd_amount-arithmetic-inconsistency-upd.h" #include "taler-auditor-httpd_coin-inconsistency-get.h" -#include "taler-auditor-httpd_coin-inconsistency-del.h" #include "taler-auditor-httpd_row-inconsistency-get.h" -#include "taler-auditor-httpd_row-inconsistency-del.h" - #include "taler-auditor-httpd_emergency-get.h" -#include "taler-auditor-httpd_emergency-del.h" - #include "taler-auditor-httpd_emergency-by-count-get.h" -#include "taler-auditor-httpd_emergency-by-count-del.h" - #include \ "taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-get.h" -#include \ - "taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-del.h" - #include "taler-auditor-httpd_purse-not-closed-inconsistencies-get.h" -#include "taler-auditor-httpd_purse-not-closed-inconsistencies-del.h" - #include "taler-auditor-httpd_reserve-balance-insufficient-inconsistency-get.h" -#include "taler-auditor-httpd_reserve-balance-insufficient-inconsistency-del.h" - #include "taler-auditor-httpd_bad-sig-losses-get.h" -#include "taler-auditor-httpd_bad-sig-losses-del.h" -#include "taler-auditor-httpd_bad-sig-losses-upd.h" - #include "taler-auditor-httpd_closure-lags-get.h" -#include "taler-auditor-httpd_closure-lags-del.h" - -#include "taler-auditor-httpd_progress-get.h" - #include "taler-auditor-httpd_refreshes-hanging-get.h" -#include "taler-auditor-httpd_refreshes-hanging-del.h" - #include "taler-auditor-httpd_mhd.h" #include "taler-auditor-httpd.h" - +#include "taler-auditor-httpd_delete_generic.h" #include "taler-auditor-httpd_patch_generic_suppressed.h" -#include "taler-auditor-httpd_emergency-by-count-upd.h" -#include "taler-auditor-httpd_row-inconsistency-upd.h" -#include "taler-auditor-httpd_purse-not-closed-inconsistencies-upd.h" -#include "taler-auditor-httpd_reserve-balance-insufficient-inconsistency-upd.h" -#include "taler-auditor-httpd_coin-inconsistency-upd.h" -#include \ - "taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-upd.h" -#include "taler-auditor-httpd_refreshes-hanging-upd.h" -#include "taler-auditor-httpd_emergency-upd.h" -#include "taler-auditor-httpd_closure-lags-upd.h" -#include "taler-auditor-httpd_row-minor-inconsistencies-upd.h" - -#include "taler-auditor-httpd_reserve-in-inconsistency-del.h" #include "taler-auditor-httpd_reserve-in-inconsistency-get.h" -#include "taler-auditor-httpd_reserve-in-inconsistency-upd.h" - -#include "taler-auditor-httpd_reserve-not-closed-inconsistency-del.h" #include "taler-auditor-httpd_reserve-not-closed-inconsistency-get.h" -#include "taler-auditor-httpd_reserve-not-closed-inconsistency-upd.h" - -#include "taler-auditor-httpd_denominations-without-sigs-del.h" #include "taler-auditor-httpd_denominations-without-sigs-get.h" -#include "taler-auditor-httpd_denominations-without-sigs-upd.h" - -#include "taler-auditor-httpd_misattribution-in-inconsistency-del.h" #include "taler-auditor-httpd_misattribution-in-inconsistency-get.h" -#include "taler-auditor-httpd_misattribution-in-inconsistency-upd.h" - #include "taler-auditor-httpd_reserves-get.h" #include "taler-auditor-httpd_purses-get.h" - #include "taler-auditor-httpd_historic-denomination-revenue-get.h" #include "taler-auditor-httpd_historic-reserve-summary-get.h" - -#include "taler-auditor-httpd_denomination-pending-del.h" #include "taler-auditor-httpd_denomination-pending-get.h" -#include "taler-auditor-httpd_denomination-pending-upd.h" - -#include "taler-auditor-httpd_wire-format-inconsistency-del.h" #include "taler-auditor-httpd_wire-format-inconsistency-get.h" -#include "taler-auditor-httpd_wire-format-inconsistency-upd.h" - -#include "taler-auditor-httpd_wire-out-inconsistency-del.h" #include "taler-auditor-httpd_wire-out-inconsistency-get.h" -#include "taler-auditor-httpd_wire-out-inconsistency-upd.h" - -#include "taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-del.h" #include "taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-get.h" -#include "taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-upd.h" - -#include "taler-auditor-httpd_row-minor-inconsistencies-del.h" #include "taler-auditor-httpd_row-minor-inconsistencies-get.h" -#include "taler-auditor-httpd_row-minor-inconsistencies-upd.h" - -#include "taler-auditor-httpd_fee-time-inconsistency-del.h" #include "taler-auditor-httpd_fee-time-inconsistency-get.h" -#include "taler-auditor-httpd_fee-time-inconsistency-upd.h" - #include "taler-auditor-httpd_balances-get.h" +#include "taler-auditor-httpd_progress-get.h" + /** * Auditor protocol version string. @@ -149,6 +82,10 @@ */ #define AUDITOR_PROTOCOL_VERSION "1:0:1" +/** + * Salt we use when doing the KDF for access. + */ +#define KDF_SALT "auditor-standard-auth" /** * Backlog for listen operation on unix domain sockets. @@ -197,6 +134,11 @@ static unsigned int connection_timeout = 30; static int global_ret; /** + * Disables authentication checks. + */ +static int disable_auth; + +/** * Port to run the daemon on. */ static uint16_t serve_port; @@ -206,9 +148,14 @@ static uint16_t serve_port; */ char *TAH_currency; -// FIXME: this is done in a very weird way, needs review! -char *TMA_auth; +/** + * Authorization code to use. + */ +static struct GNUNET_HashCode TAH_auth; +/** + * Prefix required for the access token. + */ #define RFC_8959_PREFIX "secret-token:" @@ -328,48 +275,28 @@ extract_token (const char **auth) } -enum GNUNET_GenericReturnValue -TMH_check_auth (const char *token) +static enum GNUNET_GenericReturnValue +check_auth (const char *token) { struct GNUNET_HashCode val; - struct GNUNET_HashCode salt; - struct GNUNET_HashCode tok; - - char *dec = "auditor-standard-auth"; - size_t dec_len = strlen ("auditor-standard-auth"); if (NULL == token) return GNUNET_SYSERR; - token += strlen (RFC_8959_PREFIX); - GNUNET_STRINGS_string_to_data (token, - strlen (token), - &tok, - sizeof (tok)); - if (NULL != TMA_auth) - { - GNUNET_STRINGS_string_to_data (TMA_auth, - strlen (TMA_auth), - &salt, - sizeof (salt)); - } - else - { - memset (&salt, - 0, - sizeof (salt)); - } GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_kdf (&val, sizeof (val), - &salt, - sizeof (salt), - dec, - dec_len, + KDF_SALT, + strlen (KDF_SALT), + token, + strlen (token), NULL, 0)); - - return (0 == GNUNET_memcmp (&val, &tok)) + /* We compare hashes instead of directly comparing + tokens to minimize side-channel attacks on token length */ + return (0 == + GNUNET_memcmp_priv (&val, + &TAH_auth)) ? GNUNET_OK : GNUNET_SYSERR; } @@ -406,8 +333,12 @@ handle_mhd_request (void *cls, .method = MHD_HTTP_METHOD_PUT, .mime_type = "application/json", .handler = &TAH_DEPOSIT_CONFIRMATION_handler, - .response_code = MHD_HTTP_OK, - .requires_auth = true + .response_code = MHD_HTTP_OK + }, + { + .url = "/spa", + .method = MHD_HTTP_METHOD_GET, + .handler = &TAH_spa_handler }, { "/monitoring/deposit-confirmation", @@ -421,7 +352,8 @@ handle_mhd_request (void *cls, { "/monitoring/deposit-confirmation", MHD_HTTP_METHOD_DELETE, "application/json", NULL, 0, - &TAH_DEPOSIT_CONFIRMATION_handler_delete, MHD_HTTP_OK, true }, + &TAH_delete_handler_generic, MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_DEPOSIT_CONFIRMATION }, { "/monitoring/amount-arithmetic-inconsistency", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, @@ -429,7 +361,8 @@ handle_mhd_request (void *cls, { "/monitoring/amount-arithmetic-inconsistency", MHD_HTTP_METHOD_DELETE, "application/json", NULL, 0, - &TAH_AMOUNT_ARITHMETIC_INCONSISTENCY_handler_delete, MHD_HTTP_OK, true }, + &TAH_delete_handler_generic, MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_AMOUNT_ARITHMETIC_INCONSISTENCY }, { "/monitoring/amount-arithmetic-inconsistency", MHD_HTTP_METHOD_PATCH, @@ -448,11 +381,13 @@ handle_mhd_request (void *cls, { "/monitoring/coin-inconsistency", MHD_HTTP_METHOD_DELETE, "application/json", NULL, 0, - &TAH_COIN_INCONSISTENCY_handler_delete, MHD_HTTP_OK, true }, + &TAH_delete_handler_generic, MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_COIN_INCONSISTENCY }, { "/monitoring/coin-inconsistency", MHD_HTTP_METHOD_PATCH, "application/json", NULL, 0, - &TAH_COIN_INCONSISTENCY_handler_update, MHD_HTTP_OK, true }, + &TAH_patch_handler_generic_suppressed, MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_COIN_INCONSISTENCY }, { "/monitoring/row-inconsistency", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, @@ -460,11 +395,13 @@ handle_mhd_request (void *cls, { "/monitoring/row-inconsistency", MHD_HTTP_METHOD_DELETE, "application/json", NULL, 0, - &TAH_ROW_INCONSISTENCY_handler_delete, MHD_HTTP_OK, true }, + &TAH_delete_handler_generic, MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_ROW_INCONSISTENCY}, { "/monitoring/row-inconsistency", MHD_HTTP_METHOD_PATCH, "application/json", NULL, 0, - &TAH_ROW_INCONSISTENCY_handler_update, MHD_HTTP_OK, true }, + &TAH_patch_handler_generic_suppressed, MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_ROW_INCONSISTENCY }, { "/monitoring/bad-sig-losses", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, @@ -473,13 +410,15 @@ handle_mhd_request (void *cls, { "/monitoring/bad-sig-losses", MHD_HTTP_METHOD_DELETE, "application/json", NULL, 0, - &TAH_BAD_SIG_LOSSES_handler_delete, - MHD_HTTP_OK, true }, + &TAH_delete_handler_generic, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_BAD_SIG_LOSSES}, { "/monitoring/bad-sig-losses", MHD_HTTP_METHOD_PATCH, "application/json", NULL, 0, - &TAH_BAD_SIG_LOSSES_handler_update, - MHD_HTTP_OK, true }, + &TAH_patch_handler_generic_suppressed, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_BAD_SIG_LOSSES }, { "/monitoring/closure-lags", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, @@ -488,13 +427,15 @@ handle_mhd_request (void *cls, { "/monitoring/closure-lags", MHD_HTTP_METHOD_DELETE, "application/json", NULL, 0, - &TAH_CLOSURE_LAGS_handler_delete, - MHD_HTTP_OK, true }, + &TAH_delete_handler_generic, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_CLOSURE_LAGS }, { "/monitoring/closure-lags", MHD_HTTP_METHOD_PATCH, "application/json", NULL, 0, - &TAH_CLOSURE_LAGS_handler_update, - MHD_HTTP_OK, true }, + &TAH_patch_handler_generic_suppressed, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_CLOSURE_LAGS }, { "/monitoring/emergency", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, @@ -503,13 +444,15 @@ handle_mhd_request (void *cls, { "/monitoring/emergency", MHD_HTTP_METHOD_DELETE, "application/json", NULL, 0, - &TAH_EMERGENCY_handler_delete, - MHD_HTTP_OK, true }, + &TAH_delete_handler_generic, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_EMERGENCY }, { "/monitoring/emergency", MHD_HTTP_METHOD_PATCH, "application/json", NULL, 0, - &TAH_EMERGENCY_handler_update, - MHD_HTTP_OK, true }, + &TAH_patch_handler_generic_suppressed, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_EMERGENCY }, { "/monitoring/refreshes-hanging", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, @@ -518,13 +461,15 @@ handle_mhd_request (void *cls, { "/monitoring/refreshes-hanging", MHD_HTTP_METHOD_DELETE, "application/json", NULL, 0, - &TAH_REFRESHES_HANGING_handler_delete, - MHD_HTTP_OK, true }, + &TAH_delete_handler_generic, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_REFRESHES_HANGING }, { "/monitoring/refreshes-hanging", MHD_HTTP_METHOD_PATCH, "application/json", NULL, 0, - &TAH_REFRESHES_HANGING_handler_update, - MHD_HTTP_OK, true }, + &TAH_patch_handler_generic_suppressed, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_REFRESHES_HANGING }, { "/monitoring/denomination-key-validity-withdraw-inconsistency", MHD_HTTP_METHOD_GET, "application/json", @@ -535,19 +480,16 @@ handle_mhd_request (void *cls, MHD_HTTP_METHOD_DELETE, "application/json", NULL, 0, - &TAH_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_handler_delete, - MHD_HTTP_OK, true }, + &TAH_delete_handler_generic, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY }, { "/monitoring/denomination-key-validity-withdraw-inconsistency", MHD_HTTP_METHOD_PATCH, "application/json", NULL, 0, - &TAH_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_handler_update, - MHD_HTTP_OK, true }, - { "/monitoring/progress", MHD_HTTP_METHOD_GET, - "application/json", - NULL, 0, - &TAH_PROGRESS_handler_get, - MHD_HTTP_OK, true }, + &TAH_patch_handler_generic_suppressed, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY }, { "/monitoring/reserve-balance-insufficient-inconsistency", MHD_HTTP_METHOD_GET, "application/json", @@ -558,14 +500,16 @@ handle_mhd_request (void *cls, MHD_HTTP_METHOD_DELETE, "application/json", NULL, 0, - &TAH_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_handler_delete, - MHD_HTTP_OK, true }, + &TAH_delete_handler_generic, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY }, { "/monitoring/reserve-balance-insufficient-inconsistency", MHD_HTTP_METHOD_PATCH, "application/json", NULL, 0, - &TAH_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_handler_update, - MHD_HTTP_OK, true }, + &TAH_patch_handler_generic_suppressed, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY }, { "/monitoring/purse-not-closed-inconsistencies", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, @@ -574,13 +518,15 @@ handle_mhd_request (void *cls, { "/monitoring/purse-not-closed-inconsistencies", MHD_HTTP_METHOD_DELETE, "application/json", NULL, 0, - &TAH_PURSE_NOT_CLOSED_INCONSISTENCIES_handler_delete, - MHD_HTTP_OK, true }, + &TAH_delete_handler_generic, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_PURSE_NOT_CLOSED_INCONSISTENCY }, { "/monitoring/purse-not-closed-inconsistencies", MHD_HTTP_METHOD_PATCH, "application/json", NULL, 0, - &TAH_PURSE_NOT_CLOSED_INCONSISTENCIES_handler_update, - MHD_HTTP_OK, true }, + &TAH_patch_handler_generic_suppressed, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_PURSE_NOT_CLOSED_INCONSISTENCY }, { "/monitoring/emergency-by-count", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, @@ -589,13 +535,15 @@ handle_mhd_request (void *cls, { "/monitoring/emergency-by-count", MHD_HTTP_METHOD_DELETE, "application/json", NULL, 0, - &TAH_EMERGENCY_BY_COUNT_handler_delete, - MHD_HTTP_OK, true }, + &TAH_delete_handler_generic, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_EMERGENCY_BY_COUNT }, { "/monitoring/emergency-by-count", MHD_HTTP_METHOD_PATCH, "application/json", NULL, 0, - &TAH_EMERGENCY_BY_COUNT_handler_update, - MHD_HTTP_OK, true }, + &TAH_patch_handler_generic_suppressed, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_EMERGENCY_BY_COUNT }, { "/monitoring/reserve-in-inconsistency", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, @@ -604,13 +552,15 @@ handle_mhd_request (void *cls, { "/monitoring/reserve-in-inconsistency", MHD_HTTP_METHOD_DELETE, "application/json", NULL, 0, - &TAH_RESERVE_IN_INCONSISTENCY_handler_delete, - MHD_HTTP_OK, true }, + &TAH_delete_handler_generic, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_RESERVE_IN_INCONSISTENCY }, { "/monitoring/reserve-in-inconsistency", MHD_HTTP_METHOD_PATCH, "application/json", NULL, 0, - &TAH_RESERVE_IN_INCONSISTENCY_handler_update, - MHD_HTTP_OK, true }, + &TAH_patch_handler_generic_suppressed, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_RESERVE_IN_INCONSISTENCY }, { "/monitoring/reserve-not-closed-inconsistency", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, @@ -619,13 +569,15 @@ handle_mhd_request (void *cls, { "/monitoring/reserve-not-closed-inconsistency", MHD_HTTP_METHOD_DELETE, "application/json", NULL, 0, - &TAH_RESERVE_NOT_CLOSED_INCONSISTENCY_handler_delete, - MHD_HTTP_OK, true }, + &TAH_delete_handler_generic, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_RESERVE_NOT_CLOSED_INCONSISTENCY }, { "/monitoring/reserve-not-closed-inconsistency", MHD_HTTP_METHOD_PATCH, "application/json", NULL, 0, - &TAH_RESERVE_NOT_CLOSED_INCONSISTENCY_handler_update, - MHD_HTTP_OK, true }, + &TAH_patch_handler_generic_suppressed, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_RESERVE_NOT_CLOSED_INCONSISTENCY }, { "/monitoring/denominations-without-sigs", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, @@ -634,13 +586,15 @@ handle_mhd_request (void *cls, { "/monitoring/denominations-without-sigs", MHD_HTTP_METHOD_DELETE, "application/json", NULL, 0, - &TAH_DENOMINATIONS_WITHOUT_SIGS_handler_delete, - MHD_HTTP_OK, true }, + &TAH_delete_handler_generic, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_DENOMINATIONS_WITHOUT_SIG }, { "/monitoring/denominations-without-sigs", MHD_HTTP_METHOD_PATCH, "application/json", NULL, 0, - &TAH_DENOMINATIONS_WITHOUT_SIGS_handler_update, - MHD_HTTP_OK, true }, + &TAH_patch_handler_generic_suppressed, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_DENOMINATIONS_WITHOUT_SIG }, { "/monitoring/misattribution-in-inconsistency", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, @@ -649,13 +603,15 @@ handle_mhd_request (void *cls, { "/monitoring/misattribution-in-inconsistency", MHD_HTTP_METHOD_DELETE, "application/json", NULL, 0, - &TAH_MISATTRIBUTION_IN_INCONSISTENCY_handler_delete, - MHD_HTTP_OK, true }, + &TAH_delete_handler_generic, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_MISATTRIBUTION_IN_INCONSISTENCY }, { "/monitoring/misattribution-in-inconsistency", MHD_HTTP_METHOD_PATCH, "application/json", NULL, 0, - &TAH_MISATTRIBUTION_IN_INCONSISTENCY_handler_update, - MHD_HTTP_OK, true }, + &TAH_patch_handler_generic_suppressed, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_MISATTRIBUTION_IN_INCONSISTENCY }, { "/monitoring/reserves", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, @@ -679,8 +635,9 @@ handle_mhd_request (void *cls, { "/monitoring/denomination-pending", MHD_HTTP_METHOD_DELETE, "application/json", NULL, 0, - &TAH_DENOMINATION_PENDING_handler_delete, - MHD_HTTP_OK, true }, + &TAH_delete_handler_generic, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_DENOMINATION_PENDING }, { "/monitoring/historic-reserve-summary", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, @@ -694,13 +651,15 @@ handle_mhd_request (void *cls, { "/monitoring/wire-format-inconsistency", MHD_HTTP_METHOD_DELETE, "application/json", NULL, 0, - &TAH_WIRE_FORMAT_INCONSISTENCY_handler_delete, - MHD_HTTP_OK, true }, + &TAH_delete_handler_generic, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_WIRE_FORMAT_INCONSISTENCY }, { "/monitoring/wire-format-inconsistency", MHD_HTTP_METHOD_PATCH, "application/json", NULL, 0, - &TAH_WIRE_FORMAT_INCONSISTENCY_handler_update, - MHD_HTTP_OK, true }, + &TAH_patch_handler_generic_suppressed, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_WIRE_FORMAT_INCONSISTENCY }, { "/monitoring/wire-out-inconsistency", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, @@ -709,13 +668,15 @@ handle_mhd_request (void *cls, { "/monitoring/wire-out-inconsistency", MHD_HTTP_METHOD_DELETE, "application/json", NULL, 0, - &TAH_WIRE_OUT_INCONSISTENCY_handler_delete, - MHD_HTTP_OK, true }, + &TAH_delete_handler_generic, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_WIRE_OUT_INCONSISTENCY }, { "/monitoring/wire-out-inconsistency", MHD_HTTP_METHOD_PATCH, "application/json", NULL, 0, - &TAH_WIRE_OUT_INCONSISTENCY_handler_update, - MHD_HTTP_OK, true }, + &TAH_patch_handler_generic_suppressed, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_WIRE_OUT_INCONSISTENCY }, { "/monitoring/reserve-balance-summary-wrong-inconsistency", MHD_HTTP_METHOD_GET, "application/json", @@ -726,14 +687,16 @@ handle_mhd_request (void *cls, MHD_HTTP_METHOD_DELETE, "application/json", NULL, 0, - &TAH_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_handler_delete, - MHD_HTTP_OK, true }, + &TAH_delete_handler_generic, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY }, { "/monitoring/reserve-balance-summary-wrong-inconsistency", MHD_HTTP_METHOD_PATCH, "application/json", NULL, 0, - &TAH_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_handler_update, - MHD_HTTP_OK, true }, + &TAH_patch_handler_generic_suppressed, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY }, { "/monitoring/row-minor-inconsistencies", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, @@ -742,13 +705,15 @@ handle_mhd_request (void *cls, { "/monitoring/row-minor-inconsistencies", MHD_HTTP_METHOD_DELETE, "application/json", NULL, 0, - &TAH_ROW_MINOR_INCONSISTENCIES_handler_delete, - MHD_HTTP_OK, true }, + &TAH_delete_handler_generic, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_ROW_MINOR_INCONSISTENCY }, { "/monitoring/row-minor-inconsistencies", MHD_HTTP_METHOD_PATCH, "application/json", NULL, 0, - &TAH_ROW_MINOR_INCONSISTENCIES_handler_update, - MHD_HTTP_OK, true }, + &TAH_patch_handler_generic_suppressed, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_ROW_MINOR_INCONSISTENCY }, { "/monitoring/fee-time-inconsistency", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, @@ -757,18 +722,25 @@ handle_mhd_request (void *cls, { "/monitoring/fee-time-inconsistency", MHD_HTTP_METHOD_DELETE, "application/json", NULL, 0, - &TAH_FEE_TIME_INCONSISTENCY_handler_delete, - MHD_HTTP_OK, true }, + &TAH_delete_handler_generic, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_FEE_TIME_INCONSISTENCY }, { "/monitoring/fee-time-inconsistency", MHD_HTTP_METHOD_PATCH, "application/json", NULL, 0, - &TAH_FEE_TIME_INCONSISTENCY_handler_update, - MHD_HTTP_OK, true }, + &TAH_patch_handler_generic_suppressed, + MHD_HTTP_OK, true, + .table = TALER_AUDITORDB_FEE_TIME_INCONSISTENCY }, { "/monitoring/balances", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, &TAH_BALANCES_handler_get, MHD_HTTP_OK, true }, + { "/monitoring/progress", MHD_HTTP_METHOD_GET, + "application/json", + NULL, 0, + &TAH_PROGRESS_handler_get, + MHD_HTTP_OK, true }, { "/config", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, &handle_config, MHD_HTTP_OK, false }, @@ -795,7 +767,7 @@ handle_mhd_request (void *cls, size_t ulen = strlen (url) + 1; char d[ulen]; /* const */ struct TAH_RequestHandler *match = NULL; - bool url_match; + bool url_match = false; (void) cls; (void) version; @@ -837,11 +809,11 @@ handle_mhd_request (void *cls, { /* const */ struct TAH_RequestHandler *rh = &handlers[i]; - if ( (0 == strcasecmp (url, - rh->url)) || - ( (0 == strncasecmp (url, - rh->url, - strlen (rh->url))) && + if ( (0 == strcmp (url, + rh->url)) || + ( (0 == strncmp (url, + rh->url, + strlen (rh->url))) && ('/' == url[strlen (rh->url)]) ) ) { url_match = true; @@ -850,16 +822,22 @@ handle_mhd_request (void *cls, rh->method)) ) { match = rh; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Matched %s\n", + rh->url); break; } } } if (NULL == match) { - GNUNET_break_op (0); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Could not find handler for `%s'\n", + url); goto not_found; } - if (match->requires_auth) + if (match->requires_auth && + (0 == disable_auth) ) { const char *auth; @@ -885,7 +863,7 @@ handle_mhd_request (void *cls, "' prefix or 'Bearer' missing in 'Authorization' header"); if (GNUNET_OK != - TMH_check_auth (auth)) + check_auth (auth)) { GNUNET_break_op (0); return TALER_MHD_reply_with_error ( @@ -905,7 +883,7 @@ handle_mhd_request (void *cls, not_found: if (url_match) { - /* TODO: return list of allowed methods... */ + /* FIXME: return list of allowed methods... */ GNUNET_break (0); return TALER_MHD_reply_with_error ( connection, @@ -915,7 +893,7 @@ not_found: } #define NOT_FOUND \ - "<html><title>404: not found</title><body>auditor endpoints have been moved to /monitoring/...</body></html>" + "<html><title>404: not found</title><body>auditor endpoints have been moved to /monitoring/...</body></html>" return TALER_MHD_reply_static (connection, MHD_HTTP_NOT_FOUND, "text/html", @@ -1110,18 +1088,28 @@ run (void *cls, (void) cls; (void) args; (void) cfgfile; + if (0 == disable_auth) { const char *tok; - tok = getenv ("TALER_AUDITOR_SALT"); - - if ( (NULL != tok) && - (NULL == TMA_auth) ) - TMA_auth = GNUNET_strdup (tok); - if ( (NULL == TMA_auth) ) + tok = getenv ("TALER_AUDITOR_ACCESS_TOKEN"); + if (NULL == tok) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "TALER_AUDITOR_SALT environment variable not set\n"); + "TALER_AUDITOR_ACCESS_TOKEN environment variable not set. Disabling authentication\n"); + disable_auth = 1; + } + else + { + GNUNET_assert (GNUNET_YES == + GNUNET_CRYPTO_kdf (&TAH_auth, + sizeof (TAH_auth), + KDF_SALT, + strlen (KDF_SALT), + tok, + strlen (tok), + NULL, + 0)); } } @@ -1140,6 +1128,13 @@ run (void *cls, GNUNET_SCHEDULER_shutdown (); return; } + if (GNUNET_OK != + TAH_spa_init ()) + { + global_ret = EXIT_NOTCONFIGURED; + GNUNET_SCHEDULER_shutdown (); + return; + } TEAH_DEPOSIT_CONFIRMATION_init (); fh = TALER_MHD_bind (cfg, "auditor", @@ -1202,6 +1197,10 @@ main (int argc, "connection-close", "force HTTP connections to be closed after each request", &auditor_connection_close), + GNUNET_GETOPT_option_flag ('n', + "no-authentication", + "disable authentication checks", + &disable_auth), GNUNET_GETOPT_option_uint ('t', "timeout", "SECONDS", diff --git a/src/auditor/taler-auditor-httpd.h b/src/auditor/taler-auditor-httpd.h index 374963cca..4c023a3ed 100644 --- a/src/auditor/taler-auditor-httpd.h +++ b/src/auditor/taler-auditor-httpd.h @@ -84,7 +84,6 @@ struct TAH_RequestHandler * Function to call to handle the request. * * @param rh this struct - * @param mime_type the @e mime_type for the reply (hint, can be NULL) * @param connection the MHD connection to handle * @param[in,out] connection_cls the connection's closure (can be updated) * @param upload_data upload data @@ -109,7 +108,7 @@ struct TAH_RequestHandler */ bool requires_auth; - enum TALER_AUDITORDB_SuppressableTables table; + enum TALER_AUDITORDB_DeletableSuppressableTables table; }; diff --git a/src/auditor/taler-auditor-httpd_amount-arithmetic-inconsistency-del.c b/src/auditor/taler-auditor-httpd_amount-arithmetic-inconsistency-del.c deleted file mode 100644 index 050b6c0f5..000000000 --- a/src/auditor/taler-auditor-httpd_amount-arithmetic-inconsistency-del.c +++ /dev/null @@ -1,62 +0,0 @@ -#include "taler-auditor-httpd_amount-arithmetic-inconsistency-del.h" - - -MHD_RESULT -TAH_AMOUNT_ARITHMETIC_INCONSISTENCY_handler_delete (struct - TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - - enum GNUNET_DB_QueryStatus qs; - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - - // execute the transaction - qs = TAH_plugin->delete_amount_arithmetic_inconsistency (TAH_plugin->cls, - row_id); - - if (0 > qs) - { - // goes in here if there was an error with the transaction - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - TALER_LOG_WARNING ( - "Failed to handle DELETE /amount-arithmetic-inconsistency/ %s\n", - args[1]); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - } - - // on success? - return TALER_MHD_REPLY_JSON_PACK (connection, - MHD_HTTP_NO_CONTENT, - GNUNET_JSON_pack_string ("status", - "AMOUNT_ARITHMETIC_INCONSISTENCY_OK")); - -}
\ No newline at end of file diff --git a/src/auditor/taler-auditor-httpd_amount-arithmetic-inconsistency-del.h b/src/auditor/taler-auditor-httpd_amount-arithmetic-inconsistency-del.h deleted file mode 100644 index 90bc3696f..000000000 --- a/src/auditor/taler-auditor-httpd_amount-arithmetic-inconsistency-del.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef SRC_TALER_AUDITOR_HTTPD_AMOUNT_ARITHMETIC_INCONSISTENCY_DEL_H -#define SRC_TALER_AUDITOR_HTTPD_AMOUNT_ARITHMETIC_INCONSISTENCY_DEL_H - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -/** - * Initialize subsystem. - */ -void -TEAH_AMOUNT_ARITHMETIC_INCONSISTENCY_DELETE_init (void); - -/** - * Shut down subsystem. - */ -void -TEAH_AMOUNT_ARITHMETIC_INCONSISTENCY_DELETE_done (void); - -/** - * Handle a "/deposit-confirmation" request. Parses the JSON, and, if - * successful, checks the signatures and stores the result in the DB. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @param args NULL-terminated array of remaining parts of the URI broken up at '/' - * @return MHD result code - */ -MHD_RESULT -TAH_AMOUNT_ARITHMETIC_INCONSISTENCY_handler_delete (struct - TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - - -#endif // SRC_TALER_AUDITOR_HTTPD_AMOUNT_ARITHMETIC_INCONSISTENCY_DEL_H diff --git a/src/auditor/taler-auditor-httpd_amount-arithmetic-inconsistency-get.c b/src/auditor/taler-auditor-httpd_amount-arithmetic-inconsistency-get.c index e8e64e3d0..6b51b5acb 100644 --- a/src/auditor/taler-auditor-httpd_amount-arithmetic-inconsistency-get.c +++ b/src/auditor/taler-auditor-httpd_amount-arithmetic-inconsistency-get.c @@ -13,7 +13,6 @@ You should have 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 "platform.h" #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_json_lib.h> @@ -30,30 +29,32 @@ * Add deposit confirmation to the list. * * @param[in,out] cls a `json_t *` array to extend - * @param serial_id location of the @a dc in the database * @param dc struct of inconsistencies * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating */ static enum GNUNET_GenericReturnValue add_amount_arithmetic_inconsistency ( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_AmountArithmeticInconsistency *dc) { json_t *list = cls; json_t *obj; obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_int64 ("row_id", - serial_id), - GNUNET_JSON_pack_data_auto ("operation", - &dc->operation), + GNUNET_JSON_pack_uint64 ("row_id", + dc->row_id), + GNUNET_JSON_pack_uint64 ("problem_row_id", + dc->problem_row_id), + GNUNET_JSON_pack_string ("operation", + dc->operation), TALER_JSON_pack_amount ("exchange_amount", &dc->exchange_amount), TALER_JSON_pack_amount ("auditor_amount", &dc->auditor_amount), GNUNET_JSON_pack_bool ("profitable", - dc->profitable) + dc->profitable), + GNUNET_JSON_pack_bool ("suppressed", + dc->suppressed) ); GNUNET_break (0 == json_array_append_new (list, @@ -123,7 +124,6 @@ TAH_AMOUNT_ARITHMETIC_INCONSISTENCY_handler_get ( return_suppressed, &add_amount_arithmetic_inconsistency, ja); - if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); diff --git a/src/auditor/taler-auditor-httpd_amount-arithmetic-inconsistency-upd.c b/src/auditor/taler-auditor-httpd_amount-arithmetic-inconsistency-upd.c deleted file mode 100644 index 642307a2d..000000000 --- a/src/auditor/taler-auditor-httpd_amount-arithmetic-inconsistency-upd.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - 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 "platform.h" -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_json_lib.h> -#include <jansson.h> -#include <microhttpd.h> -#include <pthread.h> -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler-auditor-httpd.h" -#include "taler-auditor-httpd_amount-arithmetic-inconsistency-upd.h" - -MHD_RESULT -TAH_AMOUNT_ARITHMETIC_INCONSISTENCY_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - enum GNUNET_DB_QueryStatus qs; - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - uint64_t row_id; - - if (args[1] != NULL) - row_id = atoi (args[1]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no row id specified"); - - - struct TALER_AUDITORDB_Generic_Update gu; - - gu.row_id = row_id; - - struct GNUNET_JSON_Specification spec[] = { - - // GNUNET_JSON_spec_uint64 ("row_id", &gu.row_id), - GNUNET_JSON_spec_bool ("suppressed", &gu.suppressed), - - GNUNET_JSON_spec_end () - }; - - json_t *json; - - (void) rh; - (void) connection_cls; - (void) upload_data; - (void) upload_data_size; - { - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_post_json (connection, - connection_cls, - upload_data, - upload_data_size, - &json); - if (GNUNET_SYSERR == res) - return MHD_NO; - if ((GNUNET_NO == res) || - (NULL == json)) - return MHD_YES; - res = TALER_MHD_parse_json_data (connection, - json, - spec); - if (GNUNET_SYSERR == res) - { - json_decref (json); - return MHD_NO; /* hard failure */ - } - if (GNUNET_NO == res) - { - json_decref (json); - return MHD_YES; /* failure */ - } - } - - /* execute transaction */ - qs = TAH_plugin->update_amount_arithmetic_inconsistency (TAH_plugin->cls, - &gu); - - GNUNET_JSON_parse_free (spec); - json_decref (json); - - MHD_RESULT ret = MHD_NO; - - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "update_account"); - break; - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "unexpected serialization problem"); - break; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no updates executed"); - break; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - ret = TALER_MHD_reply_static (connection, - MHD_HTTP_NO_CONTENT, - NULL, - NULL, - 0); - break; - } - - return ret; -} diff --git a/src/auditor/taler-auditor-httpd_amount-arithmetic-inconsistency-upd.h b/src/auditor/taler-auditor-httpd_amount-arithmetic-inconsistency-upd.h deleted file mode 100644 index bbda9d3cd..000000000 --- a/src/auditor/taler-auditor-httpd_amount-arithmetic-inconsistency-upd.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_AMOUNT_ARITHMETIC_INCONSISTENCY_UPD_H -#define SRC_TALER_AUDITOR_HTTPD_AMOUNT_ARITHMETIC_INCONSISTENCY_UPD_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -MHD_RESULT -TAH_AMOUNT_ARITHMETIC_INCONSISTENCY_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif diff --git a/src/auditor/taler-auditor-httpd_bad-sig-losses-del.c b/src/auditor/taler-auditor-httpd_bad-sig-losses-del.c deleted file mode 100644 index b2333ff57..000000000 --- a/src/auditor/taler-auditor-httpd_bad-sig-losses-del.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - 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-auditor-httpd_bad-sig-losses-del.h" - - -MHD_RESULT -TAH_BAD_SIG_LOSSES_handler_delete (struct TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - - enum GNUNET_DB_QueryStatus qs; - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - - // execute the transaction - qs = TAH_plugin->delete_bad_sig_losses (TAH_plugin->cls, - row_id); - - if (0 == qs) - { - // goes in here if there was an error with the transaction - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - TALER_LOG_WARNING ( - "Failed to handle DELETE /bad-sig-losses/ %s", - args[1]); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - } - - // on success? - return TALER_MHD_REPLY_JSON_PACK (connection, - MHD_HTTP_NO_CONTENT, - GNUNET_JSON_pack_string ("status", - "BAD_SIG_LOSSES_OK")); - -} diff --git a/src/auditor/taler-auditor-httpd_bad-sig-losses-del.h b/src/auditor/taler-auditor-httpd_bad-sig-losses-del.h deleted file mode 100644 index 9073aa216..000000000 --- a/src/auditor/taler-auditor-httpd_bad-sig-losses-del.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - 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 TALER_AUDITOR_HTTPD_BAD_SIG_LOSSES_DEL_H -#define TALER_AUDITOR_HTTPD_BAD_SIG_LOSSES_DEL_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -/** - * Initialize subsystem. - */ -void -TEAH_BAD_SIG_LOSSES_DELETE_init (void); - -/** - * Shut down subsystem. - */ -void -TEAH_BAD_SIG_LOSSES_DELETE_done (void); - -/** - * Handle a "/bad-sig-losses" request. Parses the JSON, and, if - * successful, checks the signatures and stores the result in the DB. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @param args NULL-terminated array of remaining parts of the URI broken up at '/' - * @return MHD result code - */ -MHD_RESULT -TAH_BAD_SIG_LOSSES_handler_delete ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - - -#endif diff --git a/src/auditor/taler-auditor-httpd_bad-sig-losses-get.c b/src/auditor/taler-auditor-httpd_bad-sig-losses-get.c index cf53173ce..38154bdc7 100644 --- a/src/auditor/taler-auditor-httpd_bad-sig-losses-get.c +++ b/src/auditor/taler-auditor-httpd_bad-sig-losses-get.c @@ -13,8 +13,6 @@ You should have 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 "platform.h" #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_json_lib.h> @@ -26,36 +24,39 @@ #include "taler-auditor-httpd.h" #include "taler-auditor-httpd_bad-sig-losses-get.h" + /** -* Add bad-sig-losses to the list. -* -* @param[in,out] cls a `json_t *` array to extend -* @param serial_id location of the @a dc in the database -* @param dc struct of inconsistencies -* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating -*/ + * Add bad-sig-losses to the list. + * + * @param[in,out] cls a `json_t *` array to extend + * @param dc struct of inconsistencies + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ static enum GNUNET_GenericReturnValue add_bad_sig_losses ( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_BadSigLosses *dc) { json_t *list = cls; json_t *obj; obj = GNUNET_JSON_PACK ( - - GNUNET_JSON_pack_uint64 ("row_id", serial_id), - GNUNET_JSON_pack_string ("operation", dc->operation), - TALER_JSON_pack_amount ("loss", &dc->loss), + GNUNET_JSON_pack_uint64 ("row_id", + dc->row_id), + GNUNET_JSON_pack_uint64 ("problem_row_id", + dc->problem_row_id), + GNUNET_JSON_pack_string ("operation", + dc->operation), + TALER_JSON_pack_amount ("loss", + &dc->loss), GNUNET_JSON_pack_data_auto ("operation_specific_pub", - &dc->operation_specific_pub) + &dc->operation_specific_pub), + GNUNET_JSON_pack_bool ("suppressed", + dc->suppressed) ); GNUNET_break (0 == json_array_append_new (list, obj)); - - return GNUNET_OK; } @@ -71,6 +72,12 @@ TAH_BAD_SIG_LOSSES_handler_get ( { json_t *ja; enum GNUNET_DB_QueryStatus qs; + int64_t limit = -20; + uint64_t offset; + bool return_suppressed = false; + struct GNUNET_CRYPTO_EddsaPublicKey op_spec_pub; + bool filter_spec_pub = false; + const char *op; (void) rh; (void) connection_cls; @@ -85,106 +92,48 @@ TAH_BAD_SIG_LOSSES_handler_get ( TALER_EC_GENERIC_DB_SETUP_FAILED, NULL); } - ja = json_array (); - GNUNET_break (NULL != ja); - - int64_t limit = -20; - uint64_t offset; - TALER_MHD_parse_request_snumber (connection, "limit", &limit); - if (limit < 0) offset = INT64_MAX; else offset = 0; - TALER_MHD_parse_request_number (connection, "offset", &offset); - - bool return_suppressed = false; - const char *ret_s = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "return_suppressed"); - if (ret_s != NULL && strcmp (ret_s, "true") == 0) { - return_suppressed = true; - } - - const char *op = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "op"); - - - struct GNUNET_CRYPTO_EddsaPublicKey op_spec_pub; - memset (&op_spec_pub,0, sizeof(op_spec_pub)); - - bool filter_spec_pub = false; - const char *ret_osp = MHD_lookup_connection_value (connection, + const char *ret_s = MHD_lookup_connection_value (connection, MHD_GET_ARGUMENT_KIND, - "use_op_spec_pub"); - if (ret_osp != NULL && strcmp (ret_osp, "true") == 0) - { - filter_spec_pub = true; - - - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_fixed_auto ("operation_specific_pub", &op_spec_pub), - GNUNET_JSON_spec_end () - }; - - - json_t *json; + "return_suppressed"); + if (ret_s != NULL && strcmp (ret_s, "true") == 0) { - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_post_json (connection, - connection_cls, - upload_data, - upload_data_size, - &json); - if (GNUNET_SYSERR == res) - return MHD_NO; - if ((GNUNET_NO == res) || - (NULL == json)) - return MHD_YES; - res = TALER_MHD_parse_json_data (connection, - json, - spec); - if (GNUNET_SYSERR == res) - { - json_decref (json); - return MHD_NO; /* hard failure */ - } - if (GNUNET_NO == res) - { - json_decref (json); - return MHD_YES; /* failure */ - } + return_suppressed = true; } - } - + op = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "op"); + TALER_MHD_parse_request_arg_auto (connection, + "op_spec_pub", + &op_spec_pub, + filter_spec_pub); + ja = json_array (); + GNUNET_break (NULL != ja); qs = TAH_plugin->get_bad_sig_losses ( TAH_plugin->cls, limit, offset, return_suppressed, - filter_spec_pub, - op_spec_pub, + filter_spec_pub ? &op_spec_pub : NULL, op, &add_bad_sig_losses, ja); - if (0 > qs) { - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); + GNUNET_break (0); json_decref (ja); - TALER_LOG_WARNING ( - "Failed to handle GET /bad-sig-losses\n"); return TALER_MHD_reply_with_error (connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_GENERIC_DB_FETCH_FAILED, diff --git a/src/auditor/taler-auditor-httpd_bad-sig-losses-upd.c b/src/auditor/taler-auditor-httpd_bad-sig-losses-upd.c deleted file mode 100644 index 1be070766..000000000 --- a/src/auditor/taler-auditor-httpd_bad-sig-losses-upd.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - 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 "platform.h" -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_json_lib.h> -#include <jansson.h> -#include <microhttpd.h> -#include <pthread.h> -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler-auditor-httpd.h" -#include "taler-auditor-httpd_bad-sig-losses-upd.h" - -MHD_RESULT -TAH_BAD_SIG_LOSSES_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - enum GNUNET_DB_QueryStatus qs; - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no row id specified"); - - - struct TALER_AUDITORDB_Generic_Update gu; - - gu.row_id = row_id; - - struct GNUNET_JSON_Specification spec[] = { - - // GNUNET_JSON_spec_uint64 ("row_id", &gu.row_id), - GNUNET_JSON_spec_bool ("suppressed", &gu.suppressed), - - GNUNET_JSON_spec_end () - }; - - json_t *json; - - (void) rh; - (void) connection_cls; - (void) upload_data; - (void) upload_data_size; - { - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_post_json (connection, - connection_cls, - upload_data, - upload_data_size, - &json); - if (GNUNET_SYSERR == res) - return MHD_NO; - if ((GNUNET_NO == res) || - (NULL == json)) - return MHD_YES; - res = TALER_MHD_parse_json_data (connection, - json, - spec); - if (GNUNET_SYSERR == res) - { - json_decref (json); - return MHD_NO; /* hard failure */ - } - if (GNUNET_NO == res) - { - json_decref (json); - return MHD_YES; /* failure */ - } - } - - /* execute transaction */ - qs = TAH_plugin->update_bad_sig_losses (TAH_plugin->cls, &gu); - - GNUNET_JSON_parse_free (spec); - json_decref (json); - - MHD_RESULT ret = MHD_NO; - - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "update_account"); - break; - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "unexpected serialization problem"); - break; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no updates executed"); - break; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - ret = TALER_MHD_reply_static (connection, - MHD_HTTP_NO_CONTENT, - NULL, - NULL, - 0); - break; - } - - return ret; -} diff --git a/src/auditor/taler-auditor-httpd_bad-sig-losses-upd.h b/src/auditor/taler-auditor-httpd_bad-sig-losses-upd.h deleted file mode 100644 index 9ab5bfbc0..000000000 --- a/src/auditor/taler-auditor-httpd_bad-sig-losses-upd.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_BAD_SIG_LOSSES_UPD_H -#define SRC_TALER_AUDITOR_HTTPD_BAD_SIG_LOSSES_UPD_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -MHD_RESULT -TAH_BAD_SIG_LOSSES_handler_update (struct TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif // SRC_TALER_AUDITOR_HTTPD_BAD_SIG_LOSSES_UPD_H diff --git a/src/auditor/taler-auditor-httpd_balances-get.c b/src/auditor/taler-auditor-httpd_balances-get.c index 86b3c3f97..7bf148a96 100644 --- a/src/auditor/taler-auditor-httpd_balances-get.c +++ b/src/auditor/taler-auditor-httpd_balances-get.c @@ -13,8 +13,6 @@ You should have 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 "platform.h" #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_json_lib.h> @@ -27,35 +25,29 @@ #include "taler-auditor-httpd_balances-get.h" /** -* Add balances to the list. -* -* @param[in,out] cls a `json_t *` array to extend -* @param serial_id location of the @a dc in the database -* @param dc struct of inconsistencies -* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating -*/ + * Add balance to the list. + * + * @param[in,out] cls a `json_t *` array to extend + * @param dc struct of with balance data + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ static enum GNUNET_GenericReturnValue process_balances ( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_Balances *dc) { json_t *list = cls; json_t *obj; obj = GNUNET_JSON_PACK ( - - GNUNET_JSON_pack_uint64 ("row_id", serial_id), - GNUNET_JSON_pack_string ("balance_key", dc->balance_key), - TALER_JSON_pack_amount ("balance_value", &dc->balance_value) - - + GNUNET_JSON_pack_string ("balance_key", + dc->balance_key), + TALER_JSON_pack_amount ("balance_value", + &dc->balance_value) ); GNUNET_break (0 == json_array_append_new (list, obj)); - - return GNUNET_OK; } @@ -71,6 +63,7 @@ TAH_BALANCES_handler_get ( { json_t *ja; enum GNUNET_DB_QueryStatus qs; + const char *balance_key; (void) rh; (void) connection_cls; @@ -85,40 +78,17 @@ TAH_BALANCES_handler_get ( TALER_EC_GENERIC_DB_SETUP_FAILED, NULL); } + balance_key + = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "balance_key"); ja = json_array (); GNUNET_break (NULL != ja); - - int64_t limit = -20; - uint64_t offset; - - TALER_MHD_parse_request_snumber (connection, - "limit", - &limit); - - if (limit < 0) - offset = INT64_MAX; - else - offset = 0; - - TALER_MHD_parse_request_number (connection, - "offset", - &offset); - - bool return_suppressed = false; - - const char *balance_key = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "balance_key"); - qs = TAH_plugin->get_balances ( TAH_plugin->cls, - limit, - offset, - return_suppressed, balance_key, &process_balances, ja); - if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); diff --git a/src/auditor/taler-auditor-httpd_balances-get.h b/src/auditor/taler-auditor-httpd_balances-get.h index 1d2fed6ca..c4b224641 100644 --- a/src/auditor/taler-auditor-httpd_balances-get.h +++ b/src/auditor/taler-auditor-httpd_balances-get.h @@ -13,24 +13,13 @@ You should have 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 SRC_TALER_AUDITOR_HTTPD_BALANCES_GET_H -#define SRC_TALER_AUDITOR_HTTPD_BALANCES_GET_H +#ifndef TALER_AUDITOR_HTTPD_BALANCES_GET_H +#define TALER_AUDITOR_HTTPD_BALANCES_GET_H #include <gnunet/gnunet_util_lib.h> #include <microhttpd.h> #include "taler-auditor-httpd.h" -/** -* Initialize subsystem. -*/ -void -TEAH_BALANCES_GET_init (void); - -/** -* Shut down subsystem. -*/ -void -TEAH_BAD_BALANCES_GET_done (void); /** * Handle a "/balances" request. diff --git a/src/auditor/taler-auditor-httpd_closure-lags-del.c b/src/auditor/taler-auditor-httpd_closure-lags-del.c deleted file mode 100644 index abf62393f..000000000 --- a/src/auditor/taler-auditor-httpd_closure-lags-del.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - 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-auditor-httpd_closure-lags-del.h" - - -MHD_RESULT -TAH_CLOSURE_LAGS_handler_delete (struct TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - - enum GNUNET_DB_QueryStatus qs; - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - - // execute the transaction - qs = TAH_plugin->delete_auditor_closure_lags (TAH_plugin->cls, - row_id); - - if (0 > qs) - { - // goes in here if there was an error with the transaction - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - TALER_LOG_WARNING ( - "Failed to handle DELETE /closure-lags/ %s\n", - args[1]); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - } - - // on success? - return TALER_MHD_REPLY_JSON_PACK (connection, - MHD_HTTP_NO_CONTENT, - GNUNET_JSON_pack_string ("status", - "CLOSURE_LAGS_OK")) - ; - -} diff --git a/src/auditor/taler-auditor-httpd_closure-lags-del.h b/src/auditor/taler-auditor-httpd_closure-lags-del.h deleted file mode 100644 index fbc2b03e1..000000000 --- a/src/auditor/taler-auditor-httpd_closure-lags-del.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_CLOSURE_LAGS_DEL_H -#define SRC_TALER_AUDITOR_HTTPD_CLOSURE_LAGS_DEL_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -/** -* Initialize subsystem. -*/ -void -TEAH_CLOSURE_LAGS_DELETE_init (void); - -/** -* Shut down subsystem. -*/ -void -TEAH_CLOSURE_LAGS_DELETE_done (void); - -/** - * Handle a "/closure-lags" request. Parses the JSON, and, if - * successful, checks the signatures and stores the result in the DB. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @param args NULL-terminated array of remaining parts of the URI broken up at '/' - * @return MHD result code - */ -MHD_RESULT -TAH_CLOSURE_LAGS_handler_delete ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif diff --git a/src/auditor/taler-auditor-httpd_closure-lags-get.c b/src/auditor/taler-auditor-httpd_closure-lags-get.c index e02c515bd..2a226ce4a 100644 --- a/src/auditor/taler-auditor-httpd_closure-lags-get.c +++ b/src/auditor/taler-auditor-httpd_closure-lags-get.c @@ -13,8 +13,6 @@ You should have 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 "platform.h" #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_json_lib.h> @@ -26,30 +24,37 @@ #include "taler-auditor-httpd.h" #include "taler-auditor-httpd_closure-lags-get.h" + /** -* Add closure-lags to the list. -* -* @param[in,out] cls a `json_t *` array to extend -* @param serial_id location of the @a dc in the database -* @param dc struct of inconsistencies -* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating -*/ + * Add closure-lags to the list. + * + * @param[in,out] cls a `json_t *` array to extend + * @param dc struct of inconsistencies + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ static enum GNUNET_GenericReturnValue process_closure_lags ( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_ClosureLags *dc) { json_t *list = cls; json_t *obj; obj = GNUNET_JSON_PACK ( - - TALER_JSON_pack_amount ("amount", &dc->amount), - TALER_JSON_pack_time_abs_human ("deadline", dc->deadline), - GNUNET_JSON_pack_data_auto ("wtid", &dc->wtid), - GNUNET_JSON_pack_string ("account", dc->account) - + GNUNET_JSON_pack_uint64 ("row_id", + dc->row_id), + GNUNET_JSON_pack_uint64 ("problem_row_id", + dc->problem_row_id), + TALER_JSON_pack_amount ("amount", + &dc->amount), + TALER_JSON_pack_time_abs_human ("deadline", + dc->deadline), + GNUNET_JSON_pack_data_auto ("wtid", + &dc->wtid), + GNUNET_JSON_pack_string ("account", + dc->account), + GNUNET_JSON_pack_bool ("suppressed", + dc->suppressed) ); GNUNET_break (0 == json_array_append_new (list, @@ -71,6 +76,9 @@ TAH_CLOSURE_LAGS_handler_get ( { json_t *ja; enum GNUNET_DB_QueryStatus qs; + int64_t limit = -20; + uint64_t offset; + bool return_suppressed = false; if (GNUNET_SYSERR == TAH_plugin->preflight (TAH_plugin->cls)) @@ -81,34 +89,28 @@ TAH_CLOSURE_LAGS_handler_get ( TALER_EC_GENERIC_DB_SETUP_FAILED, NULL); } - ja = json_array (); - GNUNET_break (NULL != ja); - - int64_t limit = -20; - uint64_t offset; - TALER_MHD_parse_request_snumber (connection, "limit", &limit); - if (limit < 0) offset = INT64_MAX; else offset = 0; - TALER_MHD_parse_request_number (connection, "offset", &offset); - - bool return_suppressed = false; - const char *ret_s = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "return_suppressed"); - if (ret_s != NULL && strcmp (ret_s, "true") == 0) { - return_suppressed = true; + const char *ret_s + = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "return_suppressed"); + if (ret_s != NULL && strcmp (ret_s, "true") == 0) + { + return_suppressed = true; + } } - + ja = json_array (); + GNUNET_break (NULL != ja); qs = TAH_plugin->get_auditor_closure_lags ( TAH_plugin->cls, limit, @@ -116,7 +118,6 @@ TAH_CLOSURE_LAGS_handler_get ( return_suppressed, &process_closure_lags, ja); - if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); @@ -126,11 +127,11 @@ TAH_CLOSURE_LAGS_handler_get ( return TALER_MHD_reply_with_error (connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_GENERIC_DB_FETCH_FAILED, - "closure-lags"); + "get_auditor_closure_lags"); } return TALER_MHD_REPLY_JSON_PACK ( connection, MHD_HTTP_OK, - GNUNET_JSON_pack_array_steal ("closure-lags", + GNUNET_JSON_pack_array_steal ("closure_lags", ja)); } diff --git a/src/auditor/taler-auditor-httpd_closure-lags-upd.c b/src/auditor/taler-auditor-httpd_closure-lags-upd.c deleted file mode 100644 index 9b043f974..000000000 --- a/src/auditor/taler-auditor-httpd_closure-lags-upd.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - 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 "platform.h" -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_json_lib.h> -#include <jansson.h> -#include <microhttpd.h> -#include <pthread.h> -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler-auditor-httpd.h" -#include "taler-auditor-httpd_closure-lags-upd.h" - -MHD_RESULT -TAH_CLOSURE_LAGS_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - enum GNUNET_DB_QueryStatus qs; - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no row id specified"); - - - struct TALER_AUDITORDB_Generic_Update gu; - - gu.row_id = row_id; - - struct GNUNET_JSON_Specification spec[] = { - - // GNUNET_JSON_spec_uint64 ("row_id", &gu.row_id), - GNUNET_JSON_spec_bool ("suppressed", &gu.suppressed), - - GNUNET_JSON_spec_end () - }; - - json_t *json; - - (void) rh; - (void) connection_cls; - (void) upload_data; - (void) upload_data_size; - { - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_post_json (connection, - connection_cls, - upload_data, - upload_data_size, - &json); - if (GNUNET_SYSERR == res) - return MHD_NO; - if ((GNUNET_NO == res) || - (NULL == json)) - return MHD_YES; - res = TALER_MHD_parse_json_data (connection, - json, - spec); - if (GNUNET_SYSERR == res) - { - json_decref (json); - return MHD_NO; /* hard failure */ - } - if (GNUNET_NO == res) - { - json_decref (json); - return MHD_YES; /* failure */ - } - } - - /* execute transaction */ - qs = TAH_plugin->update_closure_lags (TAH_plugin->cls, &gu); - - GNUNET_JSON_parse_free (spec); - json_decref (json); - - MHD_RESULT ret = MHD_NO; - - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "update_account"); - break; - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "unexpected serialization problem"); - break; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no updates executed"); - break; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - ret = TALER_MHD_reply_static (connection, - MHD_HTTP_NO_CONTENT, - NULL, - NULL, - 0); - break; - } - - return ret; -} diff --git a/src/auditor/taler-auditor-httpd_coin-inconsistency-del.c b/src/auditor/taler-auditor-httpd_coin-inconsistency-del.c deleted file mode 100644 index 1c35d3f48..000000000 --- a/src/auditor/taler-auditor-httpd_coin-inconsistency-del.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - 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-auditor-httpd_coin-inconsistency-del.h" - -MHD_RESULT -TAH_COIN_INCONSISTENCY_handler_delete (struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - - enum GNUNET_DB_QueryStatus qs; - - uint64_t row_id = atoi (args[1]); - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - - // execute the transaction - qs = TAH_plugin->delete_coin_inconsistency (TAH_plugin->cls,row_id); - - if (0 > qs) - { - // goes in here if there was an error with the transaction - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - TALER_LOG_WARNING ("Failed to handle DELETE /coin-inconsistency/ %s\n", - args[1]); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - } - - // on success? - return TALER_MHD_REPLY_JSON_PACK (connection, - MHD_HTTP_NO_CONTENT, - GNUNET_JSON_pack_string ("status", - "COIN_INCONSISTENCY_OK")); - -}
\ No newline at end of file diff --git a/src/auditor/taler-auditor-httpd_coin-inconsistency-del.h b/src/auditor/taler-auditor-httpd_coin-inconsistency-del.h deleted file mode 100644 index 65fabd05a..000000000 --- a/src/auditor/taler-auditor-httpd_coin-inconsistency-del.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_COIN_INCONSISTENCY_DEL_H -#define SRC_TALER_AUDITOR_HTTPD_COIN_INCONSISTENCY_DEL_H - - -#include <gnunet/gnunet_util_lib.h> -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -/** - * Initialize subsystem. - */ -void -TEAH_COIN_INCONSISTENCY_DELETE_init (void); - -/** - * Shut down subsystem. - */ -void -TEAH_COIN_INCONSISTENCY_DELETE_done (void); - -/** - * Handle a "/deposit-confirmation" request. Parses the JSON, and, if - * successful, checks the signatures and stores the result in the DB. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @param args NULL-terminated array of remaining parts of the URI broken up at '/' - * @return MHD result code - */ -MHD_RESULT -TAH_COIN_INCONSISTENCY_handler_delete ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - - -#endif diff --git a/src/auditor/taler-auditor-httpd_coin-inconsistency-get.c b/src/auditor/taler-auditor-httpd_coin-inconsistency-get.c index 1d96e2340..f5eb28ac0 100644 --- a/src/auditor/taler-auditor-httpd_coin-inconsistency-get.c +++ b/src/auditor/taler-auditor-httpd_coin-inconsistency-get.c @@ -13,8 +13,6 @@ You should have 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 "platform.h" #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_json_lib.h> @@ -24,9 +22,9 @@ #include "taler_json_lib.h" #include "taler_mhd_lib.h" #include "taler-auditor-httpd.h" - #include "taler-auditor-httpd_coin-inconsistency-get.h" + /** * Add deposit confirmation to the list. * @@ -51,12 +49,9 @@ add_coin_inconsistency ( GNUNET_JSON_pack_data_auto ("coin_pub",&dc->coin_pub), GNUNET_JSON_pack_bool ("profitable", dc->profitable) ); - GNUNET_break (0 == json_array_append_new (list, obj)); - - return GNUNET_OK; } @@ -72,6 +67,9 @@ TAH_COIN_INCONSISTENCY_handler_get ( { json_t *ja; enum GNUNET_DB_QueryStatus qs; + int64_t limit = -20; + uint64_t offset; + bool return_suppressed = false; if (GNUNET_SYSERR == TAH_plugin->preflight (TAH_plugin->cls)) @@ -82,34 +80,27 @@ TAH_COIN_INCONSISTENCY_handler_get ( TALER_EC_GENERIC_DB_SETUP_FAILED, NULL); } - ja = json_array (); - GNUNET_break (NULL != ja); - - int64_t limit = -20; - uint64_t offset; - TALER_MHD_parse_request_snumber (connection, "limit", &limit); - if (limit < 0) offset = INT64_MAX; else offset = 0; - TALER_MHD_parse_request_number (connection, "offset", &offset); - - bool return_suppressed = false; - const char *ret_s = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "return_suppressed"); - if (ret_s != NULL && strcmp (ret_s, "true") == 0) { - return_suppressed = true; + const char *ret_s = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "return_suppressed"); + if (ret_s != NULL && strcmp (ret_s, "true") == 0) + { + return_suppressed = true; + } } - + ja = json_array (); + GNUNET_break (NULL != ja); qs = TAH_plugin->get_coin_inconsistency ( TAH_plugin->cls, limit, @@ -117,7 +108,6 @@ TAH_COIN_INCONSISTENCY_handler_get ( return_suppressed, &add_coin_inconsistency, ja); - if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); diff --git a/src/auditor/taler-auditor-httpd_coin-inconsistency-upd.c b/src/auditor/taler-auditor-httpd_coin-inconsistency-upd.c deleted file mode 100644 index 63dc00ca5..000000000 --- a/src/auditor/taler-auditor-httpd_coin-inconsistency-upd.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - 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 "platform.h" -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_json_lib.h> -#include <jansson.h> -#include <microhttpd.h> -#include <pthread.h> -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler-auditor-httpd.h" -#include "taler-auditor-httpd_coin-inconsistency-upd.h" - -MHD_RESULT -TAH_COIN_INCONSISTENCY_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - enum GNUNET_DB_QueryStatus qs; - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no row id specified"); - - - struct TALER_AUDITORDB_Generic_Update gu; - - gu.row_id = row_id; - - struct GNUNET_JSON_Specification spec[] = { - - // GNUNET_JSON_spec_uint64 ("row_id", &gu.row_id), - GNUNET_JSON_spec_bool ("suppressed", &gu.suppressed), - - GNUNET_JSON_spec_end () - }; - - json_t *json; - - (void) rh; - (void) connection_cls; - (void) upload_data; - (void) upload_data_size; - { - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_post_json (connection, - connection_cls, - upload_data, - upload_data_size, - &json); - if (GNUNET_SYSERR == res) - return MHD_NO; - if ((GNUNET_NO == res) || - (NULL == json)) - return MHD_YES; - res = TALER_MHD_parse_json_data (connection, - json, - spec); - if (GNUNET_SYSERR == res) - { - json_decref (json); - return MHD_NO; /* hard failure */ - } - if (GNUNET_NO == res) - { - json_decref (json); - return MHD_YES; /* failure */ - } - } - - /* execute transaction */ - qs = TAH_plugin->update_coin_inconsistency (TAH_plugin->cls, &gu); - - GNUNET_JSON_parse_free (spec); - json_decref (json); - - MHD_RESULT ret = MHD_NO; - - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "update_account"); - break; - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "unexpected serialization problem"); - break; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no updates executed"); - break; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - ret = TALER_MHD_reply_static (connection, - MHD_HTTP_NO_CONTENT, - NULL, - NULL, - 0); - break; - } - - return ret; -} diff --git a/src/auditor/taler-auditor-httpd_coin-inconsistency-upd.h b/src/auditor/taler-auditor-httpd_coin-inconsistency-upd.h deleted file mode 100644 index f7a179ddf..000000000 --- a/src/auditor/taler-auditor-httpd_coin-inconsistency-upd.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_COIN_INCONSISTENCY_UPD_H -#define SRC_TALER_AUDITOR_HTTPD_COIN_INCONSISTENCY_UPD_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -MHD_RESULT -TAH_COIN_INCONSISTENCY_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif diff --git a/src/auditor/taler-auditor-httpd_delete_generic.c b/src/auditor/taler-auditor-httpd_delete_generic.c new file mode 100644 index 000000000..f435454fe --- /dev/null +++ b/src/auditor/taler-auditor-httpd_delete_generic.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/> + */ +#include "platform.h" +#include <gnunet/gnunet_util_lib.h> +#include <gnunet/gnunet_json_lib.h> +#include <jansson.h> +#include <microhttpd.h> +#include <pthread.h> +#include "taler_json_lib.h" +#include "taler_mhd_lib.h" +#include "taler-auditor-httpd.h" +#include "taler-auditor-httpd_delete_generic.h" + + +MHD_RESULT +TAH_delete_handler_generic ( + struct TAH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size, + const char *const args[]) +{ + enum GNUNET_DB_QueryStatus qs; + unsigned long long row_id; + char dummy; + + (void) connection_cls; + if (GNUNET_SYSERR == + TAH_plugin->preflight (TAH_plugin->cls)) + { + GNUNET_break (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_SETUP_FAILED, + NULL); + } + + if ((NULL == args[1]) || + (1 != sscanf (args[1], + "%llu%c", + &row_id, + &dummy))) + { + GNUNET_break_op (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, + "no row id specified"); + } + + /* execute transaction */ + qs = TAH_plugin->delete_generic (TAH_plugin->cls, + rh->table, + row_id); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_STORE_FAILED, + "db store failed"); + case GNUNET_DB_STATUS_SOFT_ERROR: + GNUNET_break (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, + "unexpected serialization problem"); + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, + "no delete executed"); + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + return TALER_MHD_reply_static (connection, + MHD_HTTP_NO_CONTENT, + NULL, + NULL, + 0); + } + GNUNET_break (0); + return MHD_NO; +} diff --git a/src/auditor/taler-auditor-httpd_closure-lags-upd.h b/src/auditor/taler-auditor-httpd_delete_generic.h index b77146d12..77f257822 100644 --- a/src/auditor/taler-auditor-httpd_closure-lags-upd.h +++ b/src/auditor/taler-auditor-httpd_delete_generic.h @@ -15,15 +15,18 @@ */ -#ifndef SRC_TALER_AUDITOR_HTTPD_CLOSURE_LAGS_UPD_H -#define SRC_TALER_AUDITOR_HTTPD_CLOSURE_LAGS_UPD_H - +#ifndef TALER_AUDITOR_HTTPD_DELETE_GENERIC_H +#define TALER_AUDITOR_HTTPD_DELETE_GENERIC_H +#include <gnunet/gnunet_util_lib.h> #include <microhttpd.h> #include "taler-auditor-httpd.h" +/* + * FIXME: add comment + */ MHD_RESULT -TAH_CLOSURE_LAGS_handler_update ( +TAH_delete_handler_generic( struct TAH_RequestHandler *rh, struct MHD_Connection *connection, void **connection_cls, diff --git a/src/auditor/taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-del.c b/src/auditor/taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-del.c deleted file mode 100644 index 01b243e9d..000000000 --- a/src/auditor/taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-del.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - 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-auditor-httpd_denomination-key-validity-withdraw-inconsistency-del.h" - - -MHD_RESULT -TAH_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_handler_delete (struct - TAH_RequestHandler - *rh, - struct - MHD_Connection - * - connection, - void ** - connection_cls, - const char - * - upload_data, - size_t * - upload_data_size, - const char - *const - args[]) -{ - - enum GNUNET_DB_QueryStatus qs; - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - - // execute the transaction - qs = TAH_plugin->delete_denomination_key_validity_withdraw_inconsistency ( - TAH_plugin->cls, - row_id); - - if (0 > qs) - { - // goes in here if there was an error with the transaction - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - TALER_LOG_WARNING ( - "Failed to handle DELETE /denomination-key-validity-withdraw-inconsistency/ %s", - args[1]); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - } - - // on success? - return TALER_MHD_REPLY_JSON_PACK (connection, - MHD_HTTP_NO_CONTENT, - GNUNET_JSON_pack_string ("status", - "DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_OK")); - -} diff --git a/src/auditor/taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-del.h b/src/auditor/taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-del.h deleted file mode 100644 index ce0df1f09..000000000 --- a/src/auditor/taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-del.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - 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 \ - SRC_TALER_AUDITOR_HTTPD_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_DEL_H -#define \ - SRC_TALER_AUDITOR_HTTPD_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_DEL_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -/** - * Initialize subsystem. - */ -void -TEAH_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_DELETE_init (void); - -/** - * Shut down subsystem. - */ -void -TEAH_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_DELETE_done (void); - -/** - * Handle a "/denomination-key-validity-withdraw-inconsistency" request. Parses the JSON, and, if - * successful, checks the signatures and stores the result in the DB. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @param args NULL-terminated array of remaining parts of the URI broken up at '/' - * @return MHD result code - */ -MHD_RESULT -TAH_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_handler_delete ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - - -#endif diff --git a/src/auditor/taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-get.c b/src/auditor/taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-get.c index 2a514a3bb..624ddb0e3 100644 --- a/src/auditor/taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-get.c +++ b/src/auditor/taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-get.c @@ -13,8 +13,6 @@ You should have 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 "platform.h" #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_json_lib.h> @@ -28,28 +26,33 @@ "taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-get.h" /** -* Add denomination-key-validity-withdraw-inconsistency to the list. -* -* @param[in,out] cls a `json_t *` array to extend -* @param serial_id location of the @a dc in the database -* @param dc struct of inconsistencies -* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating -*/ + * Add denomination-key-validity-withdraw-inconsistency to the list. + * + * @param[in,out] cls a `json_t *` array to extend + * @param dc struct of inconsistencies + * @return #GNUNET_OK to continue to iterate + */ static enum GNUNET_GenericReturnValue process_denomination_key_validity_withdraw_inconsistency ( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_DenominationKeyValidityWithdrawInconsistency *dc) { json_t *list = cls; json_t *obj; obj = GNUNET_JSON_PACK ( - - TALER_JSON_pack_time_abs_human ("execution_date", dc->execution_date), - GNUNET_JSON_pack_data_auto ("reserve_pub", &dc->reserve_pub), - GNUNET_JSON_pack_data_auto ("denompub_h", &dc->denompub_h) - + GNUNET_JSON_pack_uint64 ("row_id", + dc->row_id), + GNUNET_JSON_pack_uint64 ("problem_row_id", + dc->problem_row_id), + TALER_JSON_pack_time_abs_human ("execution_date", + dc->execution_date), + GNUNET_JSON_pack_data_auto ("reserve_pub", + &dc->reserve_pub), + GNUNET_JSON_pack_data_auto ("denompub_h", + &dc->denompub_h), + GNUNET_JSON_pack_bool ("suppressed", + dc->suppressed) ); GNUNET_break (0 == json_array_append_new (list, @@ -71,6 +74,9 @@ TAH_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_handler_get ( { json_t *ja; enum GNUNET_DB_QueryStatus qs; + int64_t limit = -20; + uint64_t offset; + bool return_suppressed = false; (void) rh; (void) connection_cls; @@ -85,34 +91,28 @@ TAH_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_handler_get ( TALER_EC_GENERIC_DB_SETUP_FAILED, NULL); } - ja = json_array (); - GNUNET_break (NULL != ja); - int64_t limit = -20; - uint64_t offset; - TALER_MHD_parse_request_snumber (connection, "limit", &limit); - if (limit < 0) offset = INT64_MAX; else offset = 0; - TALER_MHD_parse_request_number (connection, "offset", &offset); - - bool return_suppressed = false; - const char *ret_s = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "return_suppressed"); - if (ret_s != NULL && strcmp (ret_s, "true") == 0) { - return_suppressed = true; + const char *ret_s + = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "return_suppressed"); + if (ret_s != NULL && strcmp (ret_s, "true") == 0) + { + return_suppressed = true; + } } - - + ja = json_array (); + GNUNET_break (NULL != ja); qs = TAH_plugin->get_denomination_key_validity_withdraw_inconsistency ( TAH_plugin->cls, limit, @@ -120,7 +120,6 @@ TAH_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_handler_get ( return_suppressed, &process_denomination_key_validity_withdraw_inconsistency, ja); - if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); diff --git a/src/auditor/taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-upd.c b/src/auditor/taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-upd.c deleted file mode 100644 index d83e701fb..000000000 --- a/src/auditor/taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-upd.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - 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 "platform.h" -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_json_lib.h> -#include <jansson.h> -#include <microhttpd.h> -#include <pthread.h> -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler-auditor-httpd.h" -#include \ - "taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-upd.h" - -MHD_RESULT -TAH_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - enum GNUNET_DB_QueryStatus qs; - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no row id specified"); - - - struct TALER_AUDITORDB_Generic_Update gu; - - gu.row_id = row_id; - - struct GNUNET_JSON_Specification spec[] = { - - // GNUNET_JSON_spec_uint64 ("row_id", &gu.row_id), - GNUNET_JSON_spec_bool ("suppressed", &gu.suppressed), - - GNUNET_JSON_spec_end () - }; - - json_t *json; - - (void) rh; - (void) connection_cls; - (void) upload_data; - (void) upload_data_size; - { - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_post_json (connection, - connection_cls, - upload_data, - upload_data_size, - &json); - if (GNUNET_SYSERR == res) - return MHD_NO; - if ((GNUNET_NO == res) || - (NULL == json)) - return MHD_YES; - res = TALER_MHD_parse_json_data (connection, - json, - spec); - if (GNUNET_SYSERR == res) - { - json_decref (json); - return MHD_NO; /* hard failure */ - } - if (GNUNET_NO == res) - { - json_decref (json); - return MHD_YES; /* failure */ - } - } - - /* execute transaction */ - qs = TAH_plugin->update_denomination_key_validity_withdraw_inconsistency ( - TAH_plugin->cls, &gu); - - GNUNET_JSON_parse_free (spec); - json_decref (json); - - MHD_RESULT ret = MHD_NO; - - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "update_account"); - break; - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "unexpected serialization problem"); - break; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no updates executed"); - break; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - ret = TALER_MHD_reply_static (connection, - MHD_HTTP_NO_CONTENT, - NULL, - NULL, - 0); - break; - } - - return ret; -} diff --git a/src/auditor/taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-upd.h b/src/auditor/taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-upd.h deleted file mode 100644 index 32267bf64..000000000 --- a/src/auditor/taler-auditor-httpd_denomination-key-validity-withdraw-inconsistency-upd.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - 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 \ - SRC_TALER_AUDITOR_HTTPD_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_UPD_H -#define \ - SRC_TALER_AUDITOR_HTTPD_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_UPD_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -MHD_RESULT -TAH_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif diff --git a/src/auditor/taler-auditor-httpd_denomination-pending-del.c b/src/auditor/taler-auditor-httpd_denomination-pending-del.c deleted file mode 100644 index e275f33f7..000000000 --- a/src/auditor/taler-auditor-httpd_denomination-pending-del.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - 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-auditor-httpd_denomination-pending-del.h" - - -MHD_RESULT -TAH_DENOMINATION_PENDING_handler_delete (struct TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - - enum GNUNET_DB_QueryStatus qs; - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - - // execute the transaction - qs = TAH_plugin->delete_denomination_pending (TAH_plugin->cls, - row_id); - - if (0 == qs) - { - // goes in here if there was an error with the transaction - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - TALER_LOG_WARNING ( - "Failed to handle DELETE /denomination-pending/ %s", - args[1]); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - } - - // on success? - return TALER_MHD_REPLY_JSON_PACK (connection, - MHD_HTTP_NO_CONTENT, - GNUNET_JSON_pack_string ("status", - "DENOMINATION_PENDING_OK")); - -} diff --git a/src/auditor/taler-auditor-httpd_denomination-pending-del.h b/src/auditor/taler-auditor-httpd_denomination-pending-del.h deleted file mode 100644 index 4def8a5e7..000000000 --- a/src/auditor/taler-auditor-httpd_denomination-pending-del.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_DENOMINATION_PENDING_DEL_H -#define SRC_TALER_AUDITOR_HTTPD_DENOMINATION_PENDING_DEL_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -/** - * Initialize subsystem. - */ -void -TEAH_DENOMINATION_PENDING_DELETE_init (void); - -/** - * Shut down subsystem. - */ -void -TEAH_DENOMINATION_PENDING_DELETE_done (void); - -/** - * Handle a "/denomination-pending" request. Parses the JSON, and, if - * successful, checks the signatures and stores the result in the DB. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @param args NULL-terminated array of remaining parts of the URI broken up at '/' - * @return MHD result code - */ -MHD_RESULT -TAH_DENOMINATION_PENDING_handler_delete ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - - -#endif diff --git a/src/auditor/taler-auditor-httpd_denomination-pending-get.c b/src/auditor/taler-auditor-httpd_denomination-pending-get.c index 381e89d4a..e8e56f18e 100644 --- a/src/auditor/taler-auditor-httpd_denomination-pending-get.c +++ b/src/auditor/taler-auditor-httpd_denomination-pending-get.c @@ -13,8 +13,6 @@ You should have 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 "platform.h" #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_json_lib.h> @@ -27,13 +25,13 @@ #include "taler-auditor-httpd_denomination-pending-get.h" /** -* Add denomination-pending to the list. -* -* @param[in,out] cls a `json_t *` array to extend -* @param serial_id location of the @a dc in the database -* @param dc struct of inconsistencies -* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating -*/ + * Add denomination-pending to the list. + * + * @param[in,out] cls a `json_t *` array to extend + * @param serial_id location of the @a dc in the database + * @param dc struct of inconsistencies + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ static enum GNUNET_GenericReturnValue process_denomination_pending ( void *cls, @@ -44,21 +42,22 @@ process_denomination_pending ( json_t *obj; obj = GNUNET_JSON_PACK ( - - GNUNET_JSON_pack_data_auto ("denom_pub_hash", &dc->denom_pub_hash), - TALER_JSON_pack_amount ("denom_balance", &dc->denom_balance), - TALER_JSON_pack_amount ("denom_loss", &dc->denom_loss), - GNUNET_JSON_pack_int64 ("num_issued", dc->num_issued), - TALER_JSON_pack_amount ("denom_risk", &dc->denom_risk), - TALER_JSON_pack_amount ("recoup_loss", &dc->recoup_loss) - - + GNUNET_JSON_pack_data_auto ("denom_pub_hash", + &dc->denom_pub_hash), + TALER_JSON_pack_amount ("denom_balance", + &dc->denom_balance), + TALER_JSON_pack_amount ("denom_loss", + &dc->denom_loss), + GNUNET_JSON_pack_int64 ("num_issued", + dc->num_issued), + TALER_JSON_pack_amount ("denom_risk", + &dc->denom_risk), + TALER_JSON_pack_amount ("recoup_loss", + &dc->recoup_loss) ); GNUNET_break (0 == json_array_append_new (list, obj)); - - return GNUNET_OK; } @@ -74,6 +73,8 @@ TAH_DENOMINATION_PENDING_handler_get ( { json_t *ja; enum GNUNET_DB_QueryStatus qs; + int64_t limit = -20; + uint64_t offset; (void) rh; (void) connection_cls; @@ -88,32 +89,22 @@ TAH_DENOMINATION_PENDING_handler_get ( TALER_EC_GENERIC_DB_SETUP_FAILED, NULL); } - ja = json_array (); - GNUNET_break (NULL != ja); - - int64_t limit = -20; - uint64_t offset; - TALER_MHD_parse_request_snumber (connection, "limit", &limit); - if (limit < 0) offset = INT64_MAX; else offset = 0; - TALER_MHD_parse_request_number (connection, "offset", &offset); - - bool return_suppressed = false; - + ja = json_array (); + GNUNET_break (NULL != ja); qs = TAH_plugin->get_denomination_pending ( TAH_plugin->cls, limit, offset, - return_suppressed, &process_denomination_pending, ja); @@ -123,14 +114,15 @@ TAH_DENOMINATION_PENDING_handler_get ( json_decref (ja); TALER_LOG_WARNING ( "Failed to handle GET /denomination-pending"); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_FETCH_FAILED, - "denomination-pending"); + return TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_FETCH_FAILED, + "get_denomination_pending"); } return TALER_MHD_REPLY_JSON_PACK ( connection, MHD_HTTP_OK, - GNUNET_JSON_pack_array_steal ("denomination-pending", + GNUNET_JSON_pack_array_steal ("denomination_pending", ja)); } diff --git a/src/auditor/taler-auditor-httpd_denomination-pending-upd.c b/src/auditor/taler-auditor-httpd_denomination-pending-upd.c deleted file mode 100644 index 569cf87f0..000000000 --- a/src/auditor/taler-auditor-httpd_denomination-pending-upd.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - 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 "platform.h" -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_json_lib.h> -#include <jansson.h> -#include <microhttpd.h> -#include <pthread.h> -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler-auditor-httpd.h" -#include "taler-auditor-httpd_denomination-pending-upd.h" - -MHD_RESULT -TAH_DENOMINATION_PENDING_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - enum GNUNET_DB_QueryStatus qs; - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no row id specified"); - - - struct TALER_AUDITORDB_Generic_Update gu; - - gu.row_id = row_id; - - struct GNUNET_JSON_Specification spec[] = { - - // GNUNET_JSON_spec_uint64 ("row_id", &gu.row_id), - GNUNET_JSON_spec_bool ("suppressed", &gu.suppressed), - - GNUNET_JSON_spec_end () - }; - - json_t *json; - - (void) rh; - (void) connection_cls; - (void) upload_data; - (void) upload_data_size; - { - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_post_json (connection, - connection_cls, - upload_data, - upload_data_size, - &json); - if (GNUNET_SYSERR == res) - return MHD_NO; - if ((GNUNET_NO == res) || - (NULL == json)) - return MHD_YES; - res = TALER_MHD_parse_json_data (connection, - json, - spec); - if (GNUNET_SYSERR == res) - { - json_decref (json); - return MHD_NO; /* hard failure */ - } - if (GNUNET_NO == res) - { - json_decref (json); - return MHD_YES; /* failure */ - } - } - - /* execute transaction */ - qs = TAH_plugin->update_denomination_pending (TAH_plugin->cls, &gu); - - GNUNET_JSON_parse_free (spec); - json_decref (json); - - MHD_RESULT ret = MHD_NO; - - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "update_account"); - break; - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "unexpected serialization problem"); - break; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no updates executed"); - break; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - ret = TALER_MHD_reply_static (connection, - MHD_HTTP_NO_CONTENT, - NULL, - NULL, - 0); - break; - } - - return ret; -} diff --git a/src/auditor/taler-auditor-httpd_denomination-pending-upd.h b/src/auditor/taler-auditor-httpd_denomination-pending-upd.h deleted file mode 100644 index 54800ad43..000000000 --- a/src/auditor/taler-auditor-httpd_denomination-pending-upd.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_DENOMINATION_PENDING_UPD_H -#define SRC_TALER_AUDITOR_HTTPD_DENOMINATION_PENDING_UPD_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -MHD_RESULT -TAH_DENOMINATION_PENDING_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif diff --git a/src/auditor/taler-auditor-httpd_denominations-without-sigs-del.c b/src/auditor/taler-auditor-httpd_denominations-without-sigs-del.c deleted file mode 100644 index e94b4532c..000000000 --- a/src/auditor/taler-auditor-httpd_denominations-without-sigs-del.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - 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-auditor-httpd_denominations-without-sigs-del.h" - - -MHD_RESULT -TAH_DENOMINATIONS_WITHOUT_SIGS_handler_delete (struct TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - - enum GNUNET_DB_QueryStatus qs; - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - - // execute the transaction - qs = TAH_plugin->delete_denominations_without_sigs (TAH_plugin->cls, - row_id); - - if (0 == qs) - { - // goes in here if there was an error with the transaction - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - TALER_LOG_WARNING ( - "Failed to handle DELETE /denominations-without-sigs/ %s", - args[1]); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - } - - // on success? - return TALER_MHD_REPLY_JSON_PACK (connection, - MHD_HTTP_NO_CONTENT, - GNUNET_JSON_pack_string ("status", - "DENOMINATIONS_WITHOUT_SIGS_OK")); - -} diff --git a/src/auditor/taler-auditor-httpd_denominations-without-sigs-del.h b/src/auditor/taler-auditor-httpd_denominations-without-sigs-del.h deleted file mode 100644 index b7d8786ef..000000000 --- a/src/auditor/taler-auditor-httpd_denominations-without-sigs-del.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_DENOMINATIONS_WITHOUT_SIGS_DEL_H -#define SRC_TALER_AUDITOR_HTTPD_DENOMINATIONS_WITHOUT_SIGS_DEL_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -/** - * Initialize subsystem. - */ -void -TEAH_DENOMINATIONS_WITHOUT_SIGS_DELETE_init (void); - -/** - * Shut down subsystem. - */ -void -TEAH_DENOMINATIONS_WITHOUT_SIGS_DELETE_done (void); - -/** - * Handle a "/denominations-without-sigs" request. Parses the JSON, and, if - * successful, checks the signatures and stores the result in the DB. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @param args NULL-terminated array of remaining parts of the URI broken up at '/' - * @return MHD result code - */ -MHD_RESULT -TAH_DENOMINATIONS_WITHOUT_SIGS_handler_delete ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - - -#endif diff --git a/src/auditor/taler-auditor-httpd_denominations-without-sigs-get.c b/src/auditor/taler-auditor-httpd_denominations-without-sigs-get.c index d3e9d405e..bbe50ca52 100644 --- a/src/auditor/taler-auditor-httpd_denominations-without-sigs-get.c +++ b/src/auditor/taler-auditor-httpd_denominations-without-sigs-get.c @@ -13,8 +13,6 @@ You should have 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 "platform.h" #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_json_lib.h> @@ -26,39 +24,39 @@ #include "taler-auditor-httpd.h" #include "taler-auditor-httpd_denominations-without-sigs-get.h" + /** -* Add denominations-without-sigs to the list. -* -* @param[in,out] cls a `json_t *` array to extend -* @param serial_id location of the @a dc in the database -* @param dc struct of inconsistencies -* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating -*/ + * Add denominations-without-sigs to the list. + * + * @param[in,out] cls a `json_t *` array to extend + * @param dc struct of inconsistencies + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ static enum GNUNET_GenericReturnValue process_denominations_without_sigs ( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_DenominationsWithoutSigs *dc) { json_t *list = cls; json_t *obj; obj = GNUNET_JSON_PACK ( - - GNUNET_JSON_pack_int64 ("row_id", serial_id), - GNUNET_JSON_pack_data_auto ("denompub_h", &dc->denompub_h), - TALER_JSON_pack_amount ("value", &dc->value), - TALER_JSON_pack_time_abs_human ("start_time", dc->start_time), - TALER_JSON_pack_time_abs_human ("end_time", dc->end_time), - GNUNET_JSON_pack_bool ("suppressed", dc->suppressed) - - + GNUNET_JSON_pack_int64 ("row_id", + dc->row_id), + GNUNET_JSON_pack_data_auto ("denompub_h", + &dc->denompub_h), + TALER_JSON_pack_amount ("value", + &dc->value), + TALER_JSON_pack_time_abs_human ("start_time", + dc->start_time), + TALER_JSON_pack_time_abs_human ("end_time", + dc->end_time), + GNUNET_JSON_pack_bool ("suppressed", + dc->suppressed) ); GNUNET_break (0 == json_array_append_new (list, obj)); - - return GNUNET_OK; } @@ -74,6 +72,9 @@ TAH_DENOMINATIONS_WITHOUT_SIGS_handler_get ( { json_t *ja; enum GNUNET_DB_QueryStatus qs; + int64_t limit = -20; + uint64_t offset; + bool return_suppressed = false; (void) rh; (void) connection_cls; @@ -88,34 +89,28 @@ TAH_DENOMINATIONS_WITHOUT_SIGS_handler_get ( TALER_EC_GENERIC_DB_SETUP_FAILED, NULL); } - ja = json_array (); - GNUNET_break (NULL != ja); - - int64_t limit = -20; - uint64_t offset; - TALER_MHD_parse_request_snumber (connection, "limit", &limit); - if (limit < 0) offset = INT64_MAX; else offset = 0; - TALER_MHD_parse_request_number (connection, "offset", &offset); - - bool return_suppressed = false; - const char *ret_s = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "return_suppressed"); - if (ret_s != NULL && strcmp (ret_s, "true") == 0) { - return_suppressed = true; + const char *ret_s = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "return_suppressed"); + if (ret_s != NULL && strcmp (ret_s, "true") == 0) + { + return_suppressed = true; + } } + ja = json_array (); + GNUNET_break (NULL != ja); qs = TAH_plugin->get_denominations_without_sigs ( TAH_plugin->cls, limit, diff --git a/src/auditor/taler-auditor-httpd_denominations-without-sigs-upd.c b/src/auditor/taler-auditor-httpd_denominations-without-sigs-upd.c deleted file mode 100644 index c903b86ee..000000000 --- a/src/auditor/taler-auditor-httpd_denominations-without-sigs-upd.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - 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 "platform.h" -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_json_lib.h> -#include <jansson.h> -#include <microhttpd.h> -#include <pthread.h> -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler-auditor-httpd.h" -#include "taler-auditor-httpd_denominations-without-sigs-upd.h" - -MHD_RESULT -TAH_DENOMINATIONS_WITHOUT_SIGS_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - enum GNUNET_DB_QueryStatus qs; - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no row id specified"); - - - struct TALER_AUDITORDB_Generic_Update gu; - - gu.row_id = row_id; - - struct GNUNET_JSON_Specification spec[] = { - - // GNUNET_JSON_spec_uint64 ("row_id", &gu.row_id), - GNUNET_JSON_spec_bool ("suppressed", &gu.suppressed), - - GNUNET_JSON_spec_end () - }; - - json_t *json; - - (void) rh; - (void) connection_cls; - (void) upload_data; - (void) upload_data_size; - { - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_post_json (connection, - connection_cls, - upload_data, - upload_data_size, - &json); - if (GNUNET_SYSERR == res) - return MHD_NO; - if ((GNUNET_NO == res) || - (NULL == json)) - return MHD_YES; - res = TALER_MHD_parse_json_data (connection, - json, - spec); - if (GNUNET_SYSERR == res) - { - json_decref (json); - return MHD_NO; /* hard failure */ - } - if (GNUNET_NO == res) - { - json_decref (json); - return MHD_YES; /* failure */ - } - } - - /* execute transaction */ - qs = TAH_plugin->update_denominations_without_sigs (TAH_plugin->cls, &gu); - - GNUNET_JSON_parse_free (spec); - json_decref (json); - - MHD_RESULT ret = MHD_NO; - - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "update_account"); - break; - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "unexpected serialization problem"); - break; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no updates executed"); - break; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - ret = TALER_MHD_reply_static (connection, - MHD_HTTP_NO_CONTENT, - NULL, - NULL, - 0); - break; - } - - return ret; -} diff --git a/src/auditor/taler-auditor-httpd_denominations-without-sigs-upd.h b/src/auditor/taler-auditor-httpd_denominations-without-sigs-upd.h deleted file mode 100644 index df2980ecf..000000000 --- a/src/auditor/taler-auditor-httpd_denominations-without-sigs-upd.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_DENOMINATIONS_WITHOUT_SIGS_UPD_H -#define SRC_TALER_AUDITOR_HTTPD_DENOMINATIONS_WITHOUT_SIGS_UPD_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -MHD_RESULT -TAH_DENOMINATIONS_WITHOUT_SIGS_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation-del.c b/src/auditor/taler-auditor-httpd_deposit-confirmation-del.c deleted file mode 100644 index fadd7d479..000000000 --- a/src/auditor/taler-auditor-httpd_deposit-confirmation-del.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2024 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Affero General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - TALER is distributed in the hope that 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 - TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file taler-auditor-httpd_deposit-confirmation-del.c - * @brief Handle /deposit-confirmation delete request; - * Remove the specified entry from the database - * @author Cedric Zwahlen - */ -#include "taler-auditor-httpd_deposit-confirmation-del.h" - - -MHD_RESULT -TAH_DEPOSIT_CONFIRMATION_handler_delete (struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - - enum GNUNET_DB_QueryStatus qs; - - uint64_t row_id = atoi (args[1]); - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - - // execute the transaction - qs = TAH_plugin->delete_deposit_confirmation (TAH_plugin->cls,row_id); - - if (0 > qs) - { - // goes in here if there was an error with the transaction - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - TALER_LOG_WARNING ("Failed to handle DELETE /deposit-confirmation/ %s\n", - args[1]); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_EXCHANGE_DEPOSITS_GET_NOT_FOUND, - "row could not be found"); - - } - - // on success? - return TALER_MHD_REPLY_JSON_PACK (connection, - MHD_HTTP_NO_CONTENT, - GNUNET_JSON_pack_string ("status", - "DEPOSIT_CONFIRMATION_OK")); - -} diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation-del.h b/src/auditor/taler-auditor-httpd_deposit-confirmation-del.h deleted file mode 100644 index 032fd8aac..000000000 --- a/src/auditor/taler-auditor-httpd_deposit-confirmation-del.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - 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 Affero General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - TALER is distributed in the hope that 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 - TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file taler-auditor-httpd_deposit-confirmation-del.h - * @brief Handle DELETE /deposit-confirmation requests - * @author Cedric Zwahlen - */ -#ifndef TALER_AUDITOR_HTTPD_DEPOSIT_CONFIRMATION_DEL_H -#define TALER_AUDITOR_HTTPD_DEPOSIT_CONFIRMATION_DEL_H - -#include <gnunet/gnunet_util_lib.h> -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -/** - * Initialize subsystem. - */ -void -TEAH_DEPOSIT_CONFIRMATION_DELETE_init (void); - -/** - * Shut down subsystem. - */ -void -TEAH_DEPOSIT_CONFIRMATION_DELETE_done (void); - -/** - * Handle a "/deposit-confirmation" request. Parses the JSON, and, if - * successful, checks the signatures and stores the result in the DB. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @param args NULL-terminated array of remaining parts of the URI broken up at '/' - * @return MHD result code - */ -MHD_RESULT -TAH_DEPOSIT_CONFIRMATION_handler_delete ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - - -#endif diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation-get.c b/src/auditor/taler-auditor-httpd_deposit-confirmation-get.c index 56a90ac65..98b853105 100644 --- a/src/auditor/taler-auditor-httpd_deposit-confirmation-get.c +++ b/src/auditor/taler-auditor-httpd_deposit-confirmation-get.c @@ -13,14 +13,12 @@ You should have received a copy of the GNU Affero General Public License along with
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-
/**
* @file taler-auditor-httpd_deposit-confirmation-get.c
* @brief Handle /deposit-confirmation requests; return list of deposit confirmations from merchant
* that were not received from the exchange, by auditor.
* @author Nic Eigel
*/
-
#include "platform.h"
#include <gnunet/gnunet_util_lib.h>
#include <gnunet/gnunet_json_lib.h>
@@ -32,69 +30,77 @@ #include "taler-auditor-httpd.h"
#include "taler-auditor-httpd_deposit-confirmation-get.h"
+
/**
* Add deposit confirmation to the list.
*
* @param[in,out] cls a `json_t *` array to extend
- * @param serial_id location of the @a dc in the database
* @param dc struct of deposit confirmation
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating
*/
static enum GNUNET_GenericReturnValue
add_deposit_confirmation (
void *cls,
- uint64_t serial_id,
const struct TALER_AUDITORDB_DepositConfirmation *dc)
{
json_t *list = cls;
json_t *obj;
-
json_t *coin_pubs_json = json_array ();
json_t *coin_sigs_json = json_array ();
- for (int i = 0; dc->num_coins > i; i++)
+ GNUNET_assert (NULL != coin_pubs_json);
+ GNUNET_assert (NULL != coin_sigs_json);
+ for (unsigned int i = 0; i < dc->num_coins; i++)
{
-
- int sz_pub = sizeof(dc->coin_pubs[0]) * 9;
- char *o_pub = malloc (sz_pub);
- GNUNET_STRINGS_data_to_string (&dc->coin_pubs[i], sizeof(dc->coin_pubs[0]),
- o_pub, sz_pub);
- json_t *pub = json_string (o_pub);
- json_array_append_new (coin_pubs_json, pub);
- free (o_pub);
-
-
- int sz_sig = sizeof(dc->coin_sigs[0]) * 9;
- char *o_sig = malloc (sz_sig);
- GNUNET_STRINGS_data_to_string (&dc->coin_sigs[i], sizeof(dc->coin_sigs[0]),
- o_sig, sz_sig);
- json_t *sig = json_string (o_sig);
- json_array_append_new (coin_sigs_json, sig);
- free (o_sig);
-
+ json_t *pub;
+ json_t *sig;
+
+ pub = GNUNET_JSON_PACK (
+ GNUNET_JSON_pack_data_auto (NULL,
+ &dc->coin_pubs[i]));
+ GNUNET_assert (0 ==
+ json_array_append_new (coin_pubs_json,
+ pub));
+ sig = GNUNET_JSON_PACK (
+ GNUNET_JSON_pack_data_auto (NULL,
+ &dc->coin_sigs[i]));
+ GNUNET_assert (0 ==
+ json_array_append_new (coin_sigs_json,
+ sig));
}
obj = GNUNET_JSON_PACK (
-
- GNUNET_JSON_pack_int64 ("deposit_confirmation_serial_id", serial_id),
- GNUNET_JSON_pack_data_auto ("h_contract_terms", &dc->h_contract_terms),
- GNUNET_JSON_pack_data_auto ("h_policy", &dc->h_policy),
- GNUNET_JSON_pack_data_auto ("h_wire", &dc->h_wire),
- GNUNET_JSON_pack_timestamp ("exchange_timestamp", dc->exchange_timestamp),
- GNUNET_JSON_pack_timestamp ("refund_deadline", dc->refund_deadline),
- GNUNET_JSON_pack_timestamp ("wire_deadline", dc->wire_deadline),
- TALER_JSON_pack_amount ("total_without_fee", &dc->total_without_fee),
-
- GNUNET_JSON_pack_array_steal ("coin_pubs", coin_pubs_json),
- GNUNET_JSON_pack_array_steal ("coin_sigs", coin_sigs_json),
-
- GNUNET_JSON_pack_data_auto ("merchant_pub", &dc->merchant),
- GNUNET_JSON_pack_data_auto ("exchange_sig", &dc->exchange_sig),
- GNUNET_JSON_pack_data_auto ("exchange_pub", &dc->exchange_pub),
- GNUNET_JSON_pack_data_auto ("master_sig", &dc->master_sig)
-
+ GNUNET_JSON_pack_int64 ("deposit_confirmation_serial_id",
+ dc->row_id),
+ GNUNET_JSON_pack_data_auto ("h_contract_terms",
+ &dc->h_contract_terms),
+ GNUNET_JSON_pack_data_auto ("h_policy",
+ &dc->h_policy),
+ GNUNET_JSON_pack_data_auto ("h_wire",
+ &dc->h_wire),
+ GNUNET_JSON_pack_timestamp ("exchange_timestamp",
+ dc->exchange_timestamp),
+ GNUNET_JSON_pack_timestamp ("refund_deadline",
+ dc->refund_deadline),
+ GNUNET_JSON_pack_timestamp ("wire_deadline",
+ dc->wire_deadline),
+ TALER_JSON_pack_amount ("total_without_fee",
+ &dc->total_without_fee),
+ GNUNET_JSON_pack_array_steal ("coin_pubs",
+ coin_pubs_json),
+ GNUNET_JSON_pack_array_steal ("coin_sigs",
+ coin_sigs_json),
+ GNUNET_JSON_pack_data_auto ("merchant_pub",
+ &dc->merchant),
+ GNUNET_JSON_pack_data_auto ("exchange_sig",
+ &dc->exchange_sig),
+ GNUNET_JSON_pack_data_auto ("exchange_pub",
+ &dc->exchange_pub),
+ GNUNET_JSON_pack_data_auto ("master_sig",
+ &dc->master_sig),
+ GNUNET_JSON_pack_bool ("suppressed",
+ dc->suppressed)
);
-
GNUNET_break (0 ==
json_array_append_new (list,
obj));
@@ -113,6 +119,9 @@ TAH_DEPOSIT_CONFIRMATION_handler_get ( {
json_t *ja;
enum GNUNET_DB_QueryStatus qs;
+ bool return_suppressed = false;
+ int64_t limit = -20;
+ uint64_t offset;
(void) rh;
(void) connection_cls;
@@ -127,36 +136,29 @@ TAH_DEPOSIT_CONFIRMATION_handler_get ( TALER_EC_GENERIC_DB_SETUP_FAILED,
NULL);
}
- ja = json_array ();
- GNUNET_break (NULL != ja);
-
- bool return_suppressed = false;
-
- int64_t limit = -20; // unused here
- uint64_t offset;
-
TALER_MHD_parse_request_snumber (connection,
"limit",
&limit);
-
if (limit < 0)
offset = INT64_MAX;
else
offset = 0;
-
TALER_MHD_parse_request_number (connection,
"offset",
&offset);
-
-
- const char *ret_s = MHD_lookup_connection_value (connection,
- MHD_GET_ARGUMENT_KIND,
- "return_suppressed");
- if (ret_s != NULL && strcmp (ret_s, "true") == 0)
{
- return_suppressed = true;
+ const char *ret_s = MHD_lookup_connection_value (connection,
+ MHD_GET_ARGUMENT_KIND,
+ "return_suppressed");
+ if ( (NULL != ret_s) &&
+ (0 == strcmp (ret_s, "true")) )
+ {
+ return_suppressed = true;
+ }
}
+ ja = json_array ();
+ GNUNET_break (NULL != ja);
qs = TAH_plugin->get_deposit_confirmations (
TAH_plugin->cls,
limit,
@@ -164,7 +166,6 @@ TAH_DEPOSIT_CONFIRMATION_handler_get ( return_suppressed,
&add_deposit_confirmation,
ja);
-
if (0 > qs)
{
GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation-upd.c b/src/auditor/taler-auditor-httpd_deposit-confirmation-upd.c deleted file mode 100644 index 6b2fc70ec..000000000 --- a/src/auditor/taler-auditor-httpd_deposit-confirmation-upd.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - 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 "platform.h" -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_json_lib.h> -#include <jansson.h> -#include <microhttpd.h> -#include <pthread.h> -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler-auditor-httpd.h" -#include "taler-auditor-httpd_deposit-confirmation-upd.h" - -MHD_RESULT -TAH_DEPOSIT_CONFIRMATION_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - enum GNUNET_DB_QueryStatus qs; - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no row id specified"); - - - struct TALER_AUDITORDB_Generic_Update gu; - - gu.row_id = row_id; - - struct GNUNET_JSON_Specification spec[] = { - - // GNUNET_JSON_spec_uint64 ("row_id", &gu.row_id), - GNUNET_JSON_spec_bool ("suppressed", &gu.suppressed), - - GNUNET_JSON_spec_end () - }; - - json_t *json; - - (void) rh; - (void) connection_cls; - (void) upload_data; - (void) upload_data_size; - { - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_post_json (connection, - connection_cls, - upload_data, - upload_data_size, - &json); - if (GNUNET_SYSERR == res) - return MHD_NO; - if ((GNUNET_NO == res) || - (NULL == json)) - return MHD_YES; - res = TALER_MHD_parse_json_data (connection, - json, - spec); - if (GNUNET_SYSERR == res) - { - json_decref (json); - return MHD_NO; /* hard failure */ - } - if (GNUNET_NO == res) - { - json_decref (json); - return MHD_YES; /* failure */ - } - } - - /* execute transaction */ - qs = TAH_plugin->update_deposit_confirmations (TAH_plugin->cls, &gu); - - GNUNET_JSON_parse_free (spec); - json_decref (json); - - MHD_RESULT ret = MHD_NO; - - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "update_account"); - break; - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "unexpected serialization problem"); - break; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no updates executed"); - break; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - ret = TALER_MHD_reply_static (connection, - MHD_HTTP_NO_CONTENT, - NULL, - NULL, - 0); - break; - } - - return ret; -} diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation-upd.h b/src/auditor/taler-auditor-httpd_deposit-confirmation-upd.h deleted file mode 100644 index 764af917b..000000000 --- a/src/auditor/taler-auditor-httpd_deposit-confirmation-upd.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_DEPOSIT_CONFIRMATION_UPD_H -#define SRC_TALER_AUDITOR_HTTPD_DEPOSIT_CONFIRMATION_UPD_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -MHD_RESULT -TAH_DEPOSIT_CONFIRMATION_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation.c b/src/auditor/taler-auditor-httpd_deposit-confirmation.c index 69f51ef45..244c0ef5e 100644 --- a/src/auditor/taler-auditor-httpd_deposit-confirmation.c +++ b/src/auditor/taler-auditor-httpd_deposit-confirmation.c @@ -299,11 +299,9 @@ TAH_DEPOSIT_CONFIRMATION_handler ( NULL), GNUNET_JSON_spec_timestamp ("wire_deadline", &dc.wire_deadline), - TALER_JSON_spec_amount ("total_without_fee", TAH_currency, &dc.total_without_fee), - GNUNET_JSON_spec_array_const ("coin_pubs", &jcoin_pubs), GNUNET_JSON_spec_array_const ("coin_sigs", @@ -344,6 +342,7 @@ TAH_DEPOSIT_CONFIRMATION_handler ( if ((GNUNET_NO == res) || (NULL == json)) return MHD_YES; + dc.master_sig = es.master_sig; res = TALER_MHD_parse_json_data (connection, json, spec); diff --git a/src/auditor/taler-auditor-httpd_emergency-by-count-del.c b/src/auditor/taler-auditor-httpd_emergency-by-count-del.c deleted file mode 100644 index 4af459bf2..000000000 --- a/src/auditor/taler-auditor-httpd_emergency-by-count-del.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - 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-auditor-httpd_emergency-by-count-del.h" - - -MHD_RESULT -TAH_EMERGENCY_BY_COUNT_handler_delete (struct TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - - MHD_RESULT res; - enum GNUNET_DB_QueryStatus qs; - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - - // execute the transaction - qs = TAH_plugin->delete_emergency_by_count (TAH_plugin->cls, - row_id); - - if (0 > qs) - { - // goes in here if there was an error with the transaction - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - TALER_LOG_WARNING ( - "Failed to handle DELETE /emergency-by-count/ %s\n", - args[1]); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - } - - // on success? - return TALER_MHD_REPLY_JSON_PACK (connection, - MHD_HTTP_NO_CONTENT, - GNUNET_JSON_pack_string ("status", - "EMERGENCY_BY_COUNT_OK")); - - return res; -} diff --git a/src/auditor/taler-auditor-httpd_emergency-by-count-del.h b/src/auditor/taler-auditor-httpd_emergency-by-count-del.h deleted file mode 100644 index f8cd7bd00..000000000 --- a/src/auditor/taler-auditor-httpd_emergency-by-count-del.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_EMERGENCY_BY_COUNT_DEL_H -#define SRC_TALER_AUDITOR_HTTPD_EMERGENCY_BY_COUNT_DEL_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -/** -* Initialize subsystem. -*/ -void -TEAH_EMERGENCY_BY_COUNT_DELETE_init (void); - -/** -* Shut down subsystem. -*/ -void -TEAH_EMERGENCY_BY_COUNT_DELETE_done (void); - -/** -* Handle a "/emergency-by-count" request. Parses the JSON, and, if -* successful, checks the signatures and stores the result in the DB. -* -* @param rh context of the handler -* @param connection the MHD connection to handle -* @param[in,out] connection_cls the connection's closure (can be updated) -* @param upload_data upload data -* @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @param args NULL-terminated array of remaining parts of the URI broken up at '/' -* @return MHD result code -*/ -MHD_RESULT -TAH_EMERGENCY_BY_COUNT_handler_delete ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif diff --git a/src/auditor/taler-auditor-httpd_emergency-by-count-get.c b/src/auditor/taler-auditor-httpd_emergency-by-count-get.c index b91dbacc3..d39636cea 100644 --- a/src/auditor/taler-auditor-httpd_emergency-by-count-get.c +++ b/src/auditor/taler-auditor-httpd_emergency-by-count-get.c @@ -13,8 +13,6 @@ You should have 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 "platform.h" #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_json_lib.h> @@ -27,39 +25,43 @@ #include "taler-auditor-httpd_emergency-by-count-get.h" /** -* Add emergency-by-count to the list. -* -* @param[in,out] cls a `json_t *` array to extend -* @param serial_id location of the @a dc in the database -* @param dc struct of inconsistencies -* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating -*/ + * Add emergency-by-count to the list. + * + * @param[in,out] cls a `json_t *` array to extend + * @param dc struct of inconsistencies + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ static enum GNUNET_GenericReturnValue process_emergency_by_count ( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_EmergenciesByCount *dc) { json_t *list = cls; json_t *obj; obj = GNUNET_JSON_PACK ( - - GNUNET_JSON_pack_uint64 ("row_id", serial_id), - GNUNET_JSON_pack_data_auto ("denompub_h", &dc->denompub_h), - GNUNET_JSON_pack_int64 ("num_issued", dc->num_issued), - GNUNET_JSON_pack_int64 ("num_known", dc->num_known), - TALER_JSON_pack_amount ("risk", &dc->risk), - TALER_JSON_pack_time_abs_human ("start", dc->start), - TALER_JSON_pack_time_abs_human ("deposit_end", dc->deposit_end), - TALER_JSON_pack_amount ("value", &dc->value) - + GNUNET_JSON_pack_uint64 ("row_id", + dc->row_id), + GNUNET_JSON_pack_data_auto ("denompub_h", + &dc->denompub_h), + GNUNET_JSON_pack_int64 ("num_issued", + dc->num_issued), + GNUNET_JSON_pack_int64 ("num_known", + dc->num_known), + TALER_JSON_pack_amount ("risk", + &dc->risk), + TALER_JSON_pack_time_abs_human ("start", + dc->start), + TALER_JSON_pack_time_abs_human ("deposit_end", + dc->deposit_end), + TALER_JSON_pack_amount ("value", + &dc->value), + GNUNET_JSON_pack_bool ("suppressed", + dc->suppressed) ); GNUNET_break (0 == json_array_append_new (list, obj)); - - return GNUNET_OK; } @@ -75,6 +77,9 @@ TAH_EMERGENCY_BY_COUNT_handler_get ( { json_t *ja; enum GNUNET_DB_QueryStatus qs; + int64_t limit = -20; + uint64_t offset; + bool return_suppressed = false; (void) rh; (void) connection_cls; @@ -89,34 +94,29 @@ TAH_EMERGENCY_BY_COUNT_handler_get ( TALER_EC_GENERIC_DB_SETUP_FAILED, NULL); } - ja = json_array (); - GNUNET_break (NULL != ja); - - int64_t limit = -20; - uint64_t offset; - TALER_MHD_parse_request_snumber (connection, "limit", &limit); - if (limit < 0) offset = INT64_MAX; else offset = 0; - TALER_MHD_parse_request_number (connection, "offset", &offset); - - bool return_suppressed = false; - const char *ret_s = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "return_suppressed"); - if (ret_s != NULL && strcmp (ret_s, "true") == 0) { - return_suppressed = true; + const char *ret_s + = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "return_suppressed"); + if (ret_s != NULL && strcmp (ret_s, "true") == 0) + { + return_suppressed = true; + } } + ja = json_array (); + GNUNET_break (NULL != ja); qs = TAH_plugin->get_emergency_by_count ( TAH_plugin->cls, limit, @@ -124,7 +124,6 @@ TAH_EMERGENCY_BY_COUNT_handler_get ( return_suppressed, &process_emergency_by_count, ja); - if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); diff --git a/src/auditor/taler-auditor-httpd_emergency-by-count-upd.c b/src/auditor/taler-auditor-httpd_emergency-by-count-upd.c deleted file mode 100644 index 37c92ab28..000000000 --- a/src/auditor/taler-auditor-httpd_emergency-by-count-upd.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - 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 "platform.h" -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_json_lib.h> -#include <jansson.h> -#include <microhttpd.h> -#include <pthread.h> -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler-auditor-httpd.h" -#include "taler-auditor-httpd_emergency-by-count-upd.h" - -MHD_RESULT -TAH_EMERGENCY_BY_COUNT_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - enum GNUNET_DB_QueryStatus qs; - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no row id specified"); - - - struct TALER_AUDITORDB_Generic_Update gu; - - gu.row_id = row_id; - - struct GNUNET_JSON_Specification spec[] = { - - // GNUNET_JSON_spec_uint64 ("row_id", &gu.row_id), - GNUNET_JSON_spec_bool ("suppressed", &gu.suppressed), - - GNUNET_JSON_spec_end () - }; - - json_t *json; - - (void) rh; - (void) connection_cls; - (void) upload_data; - (void) upload_data_size; - { - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_post_json (connection, - connection_cls, - upload_data, - upload_data_size, - &json); - if (GNUNET_SYSERR == res) - return MHD_NO; - if ((GNUNET_NO == res) || - (NULL == json)) - return MHD_YES; - res = TALER_MHD_parse_json_data (connection, - json, - spec); - if (GNUNET_SYSERR == res) - { - json_decref (json); - return MHD_NO; /* hard failure */ - } - if (GNUNET_NO == res) - { - json_decref (json); - return MHD_YES; /* failure */ - } - } - - /* execute transaction */ - qs = TAH_plugin->update_emergency_by_count (TAH_plugin->cls, &gu); - - GNUNET_JSON_parse_free (spec); - json_decref (json); - - MHD_RESULT ret = MHD_NO; - - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "update_account"); - break; - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "unexpected serialization problem"); - break; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no updates executed"); - break; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - ret = TALER_MHD_reply_static (connection, - MHD_HTTP_NO_CONTENT, - NULL, - NULL, - 0); - break; - } - - return ret; -} diff --git a/src/auditor/taler-auditor-httpd_emergency-by-count-upd.h b/src/auditor/taler-auditor-httpd_emergency-by-count-upd.h deleted file mode 100644 index 15be00a9c..000000000 --- a/src/auditor/taler-auditor-httpd_emergency-by-count-upd.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_EMERGENCY_BY_COUNT_UPD_H -#define SRC_TALER_AUDITOR_HTTPD_EMERGENCY_BY_COUNT_UPD_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -MHD_RESULT -TAH_EMERGENCY_BY_COUNT_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif diff --git a/src/auditor/taler-auditor-httpd_emergency-del.c b/src/auditor/taler-auditor-httpd_emergency-del.c deleted file mode 100644 index 014190f08..000000000 --- a/src/auditor/taler-auditor-httpd_emergency-del.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - 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-auditor-httpd_emergency-del.h" - - -MHD_RESULT -TAH_EMERGENCY_handler_delete (struct TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - - enum GNUNET_DB_QueryStatus qs; - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - - // execute the transaction - qs = TAH_plugin->delete_emergency (TAH_plugin->cls, - row_id); - - if (0 > qs) - { - // goes in here if there was an error with the transaction - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - TALER_LOG_WARNING ( - "Failed to handle DELETE /emergency/ %s\n", - args[1]); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - } - - // on success? - return TALER_MHD_REPLY_JSON_PACK (connection, - MHD_HTTP_NO_CONTENT, - GNUNET_JSON_pack_string ("status", - "EMERGENCY_OK")); - -} diff --git a/src/auditor/taler-auditor-httpd_emergency-del.h b/src/auditor/taler-auditor-httpd_emergency-del.h deleted file mode 100644 index 16928dee7..000000000 --- a/src/auditor/taler-auditor-httpd_emergency-del.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_EMERGENCY_DEL_H -#define SRC_TALER_AUDITOR_HTTPD_EMERGENCY_DEL_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -/** -* Initialize subsystem. -*/ -void -TEAH_EMERGENCY_DELETE_init (void); - -/** -* Shut down subsystem. -*/ -void -TEAH_EMERGENCY_DELETE_done (void); - -/** - * Handle a "/emergency" request. Parses the JSON, and, if - * successful, checks the signatures and stores the result in the DB. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @param args NULL-terminated array of remaining parts of the URI broken up at '/' - * @return MHD result code - */ -MHD_RESULT -TAH_EMERGENCY_handler_delete ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif diff --git a/src/auditor/taler-auditor-httpd_emergency-get.c b/src/auditor/taler-auditor-httpd_emergency-get.c index 699d90400..7bfee600f 100644 --- a/src/auditor/taler-auditor-httpd_emergency-get.c +++ b/src/auditor/taler-auditor-httpd_emergency-get.c @@ -13,8 +13,6 @@ You should have 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 "platform.h" #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_json_lib.h> @@ -28,42 +26,41 @@ /** -* Add emergency to the list. -* -* @param[in,out] cls a `json_t *` array to extend -* @param serial_id location of the @a dc in the database -* @param dc struct of inconsistencies -* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating -*/ + * Add emergency to the list. + * + * @param[in,out] cls a `json_t *` array to extend + * @param dc struct of inconsistencies + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ static enum GNUNET_GenericReturnValue process_emergency ( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_Emergency *dc) { json_t *list = cls; json_t *obj; - obj = GNUNET_JSON_PACK ( - - GNUNET_JSON_pack_int64 ("row_id", serial_id), - - GNUNET_JSON_pack_data_auto ("denompub_h", &dc->denompub_h), - - TALER_JSON_pack_amount ("denom_risk", &dc->denom_risk), - TALER_JSON_pack_amount ("denom_loss", &dc->denom_loss), - - TALER_JSON_pack_time_abs_human ("deposit_start", dc->deposit_start), - TALER_JSON_pack_time_abs_human ("deposit_end", dc->deposit_end), - - TALER_JSON_pack_amount ("value", &dc->value) + GNUNET_JSON_pack_uint64 ("row_id", + dc->row_id), + GNUNET_JSON_pack_data_auto ("denompub_h", + &dc->denompub_h), + TALER_JSON_pack_amount ("denom_risk", + &dc->denom_risk), + TALER_JSON_pack_amount ("denom_loss", + &dc->denom_loss), + TALER_JSON_pack_time_abs_human ("deposit_start", + dc->deposit_start), + TALER_JSON_pack_time_abs_human ("deposit_end", + dc->deposit_end), + TALER_JSON_pack_amount ("value", + &dc->value), + GNUNET_JSON_pack_bool ("suppressed", + dc->suppressed) ); GNUNET_break (0 == json_array_append_new (list, obj)); - - return GNUNET_OK; } @@ -79,6 +76,9 @@ TAH_EMERGENCY_handler_get ( { json_t *ja; enum GNUNET_DB_QueryStatus qs; + int64_t limit = -20; + uint64_t offset; + bool return_suppressed = false; (void) rh; (void) connection_cls; @@ -93,27 +93,29 @@ TAH_EMERGENCY_handler_get ( TALER_EC_GENERIC_DB_SETUP_FAILED, NULL); } - ja = json_array (); - GNUNET_break (NULL != ja); - - int64_t limit = -20; - uint64_t offset; - TALER_MHD_parse_request_snumber (connection, "limit", &limit); - if (limit < 0) offset = INT64_MAX; else offset = 0; - TALER_MHD_parse_request_number (connection, "offset", &offset); + { + const char *ret_s + = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "return_suppressed"); + if (ret_s != NULL && strcmp (ret_s, "true") == 0) + { + return_suppressed = true; + } + } - bool return_suppressed = false; - + ja = json_array (); + GNUNET_break (NULL != ja); qs = TAH_plugin->get_emergency ( TAH_plugin->cls, limit, @@ -121,7 +123,6 @@ TAH_EMERGENCY_handler_get ( return_suppressed, &process_emergency, ja); - if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); diff --git a/src/auditor/taler-auditor-httpd_emergency-upd.c b/src/auditor/taler-auditor-httpd_emergency-upd.c deleted file mode 100644 index eba466a9f..000000000 --- a/src/auditor/taler-auditor-httpd_emergency-upd.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - 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 "platform.h" -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_json_lib.h> -#include <jansson.h> -#include <microhttpd.h> -#include <pthread.h> -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler-auditor-httpd.h" -#include "taler-auditor-httpd_emergency-upd.h" - -MHD_RESULT -TAH_EMERGENCY_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - enum GNUNET_DB_QueryStatus qs; - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no row id specified"); - - - struct TALER_AUDITORDB_Generic_Update gu; - - gu.row_id = row_id; - - struct GNUNET_JSON_Specification spec[] = { - - // GNUNET_JSON_spec_uint64 ("row_id", &gu.row_id), - GNUNET_JSON_spec_bool ("suppressed", &gu.suppressed), - - GNUNET_JSON_spec_end () - }; - - json_t *json; - - (void) rh; - (void) connection_cls; - (void) upload_data; - (void) upload_data_size; - { - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_post_json (connection, - connection_cls, - upload_data, - upload_data_size, - &json); - if (GNUNET_SYSERR == res) - return MHD_NO; - if ((GNUNET_NO == res) || - (NULL == json)) - return MHD_YES; - res = TALER_MHD_parse_json_data (connection, - json, - spec); - if (GNUNET_SYSERR == res) - { - json_decref (json); - return MHD_NO; /* hard failure */ - } - if (GNUNET_NO == res) - { - json_decref (json); - return MHD_YES; /* failure */ - } - } - - /* execute transaction */ - qs = TAH_plugin->update_emergency (TAH_plugin->cls, &gu); - - GNUNET_JSON_parse_free (spec); - json_decref (json); - - MHD_RESULT ret = MHD_NO; - - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "update_account"); - break; - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "unexpected serialization problem"); - break; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no updates executed"); - break; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - ret = TALER_MHD_reply_static (connection, - MHD_HTTP_NO_CONTENT, - NULL, - NULL, - 0); - break; - } - - return ret; -} diff --git a/src/auditor/taler-auditor-httpd_emergency-upd.h b/src/auditor/taler-auditor-httpd_emergency-upd.h deleted file mode 100644 index 3e9161bcf..000000000 --- a/src/auditor/taler-auditor-httpd_emergency-upd.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_EMERGENCY_UPD_H -#define SRC_TALER_AUDITOR_HTTPD_EMERGENCY_UPD_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -MHD_RESULT -TAH_EMERGENCY_handler_update (struct TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif // SRC_TALER_AUDITOR_HTTPD_EMERGENCY_UPD_H diff --git a/src/auditor/taler-auditor-httpd_fee-time-inconsistency-del.c b/src/auditor/taler-auditor-httpd_fee-time-inconsistency-del.c deleted file mode 100644 index 377db21ad..000000000 --- a/src/auditor/taler-auditor-httpd_fee-time-inconsistency-del.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - 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-auditor-httpd_fee-time-inconsistency-del.h" - - -MHD_RESULT -TAH_FEE_TIME_INCONSISTENCY_handler_delete (struct TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - - enum GNUNET_DB_QueryStatus qs; - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - - // execute the transaction - qs = TAH_plugin->delete_fee_time_inconsistency (TAH_plugin->cls, - row_id); - - if (0 > qs) - { - // goes in here if there was an error with the transaction - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - TALER_LOG_WARNING ( - "Failed to handle DELETE /fee-time-inconsistency/ %s\n", - args[1]); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - } - - // on success? - return TALER_MHD_REPLY_JSON_PACK (connection, - MHD_HTTP_NO_CONTENT, - GNUNET_JSON_pack_string ("status", - "FEE_TIME_INCONSISTENCY_OK")); - -} diff --git a/src/auditor/taler-auditor-httpd_fee-time-inconsistency-del.h b/src/auditor/taler-auditor-httpd_fee-time-inconsistency-del.h deleted file mode 100644 index 549b6b2b0..000000000 --- a/src/auditor/taler-auditor-httpd_fee-time-inconsistency-del.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_FEE_TIME_INCONSISTENCY_DEL_H -#define SRC_TALER_AUDITOR_HTTPD_FEE_TIME_INCONSISTENCY_DEL_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -/** -* Initialize subsystem. -*/ -void -TEAH_FEE_TIME_INCONSISTENCY_DELETE_init (void); - -/** -* Shut down subsystem. -*/ -void -TEAH_FEE_TIME_INCONSISTENCY_DELETE_done (void); - -/** - * Handle a "/fee-time-inconsistency" request. Parses the JSON, and, if - * successful, checks the signatures and stores the result in the DB. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @param args NULL-terminated array of remaining parts of the URI broken up at '/' - * @return MHD result code - */ -MHD_RESULT -TAH_FEE_TIME_INCONSISTENCY_handler_delete ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif diff --git a/src/auditor/taler-auditor-httpd_fee-time-inconsistency-get.c b/src/auditor/taler-auditor-httpd_fee-time-inconsistency-get.c index 26b8e489d..742370eb7 100644 --- a/src/auditor/taler-auditor-httpd_fee-time-inconsistency-get.c +++ b/src/auditor/taler-auditor-httpd_fee-time-inconsistency-get.c @@ -13,8 +13,6 @@ You should have 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 "platform.h" #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_json_lib.h> @@ -26,38 +24,37 @@ #include "taler-auditor-httpd.h" #include "taler-auditor-httpd_fee-time-inconsistency-get.h" + /** -* Add fee-time-inconsistency to the list. -* -* @param[in,out] cls a `json_t *` array to extend -* @param serial_id location of the @a dc in the database -* @param dc struct of inconsistencies -* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating -*/ + * Add fee-time-inconsistency to the list. + * + * @param[in,out] cls a `json_t *` array to extend + * @param dc struct of inconsistencies + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ static enum GNUNET_GenericReturnValue process_fee_time_inconsistency ( void *cls, - uint64_t serial_id, - const struct - TALER_AUDITORDB_FeeTimeInconsistency - *dc) + const struct TALER_AUDITORDB_FeeTimeInconsistency *dc) { json_t *list = cls; json_t *obj; obj = GNUNET_JSON_PACK ( - - GNUNET_JSON_pack_string ("type", dc->type), - TALER_JSON_pack_time_abs_human ("time", dc->time), - GNUNET_JSON_pack_string ("diagnostic", dc->diagnostic) - - + GNUNET_JSON_pack_uint64 ("row_id", + dc->row_id), + GNUNET_JSON_pack_uint64 ("problem_row_id", + dc->problem_row_id), + GNUNET_JSON_pack_string ("type", + dc->type), + TALER_JSON_pack_time_abs_human ("time", + dc->time), + GNUNET_JSON_pack_string ("diagnostic", + dc->diagnostic) ); GNUNET_break (0 == json_array_append_new (list, obj)); - - return GNUNET_OK; } @@ -73,6 +70,9 @@ TAH_FEE_TIME_INCONSISTENCY_handler_get ( { json_t *ja; enum GNUNET_DB_QueryStatus qs; + int64_t limit = -20; + uint64_t offset; + bool return_suppressed = false; (void) rh; (void) connection_cls; @@ -87,34 +87,29 @@ TAH_FEE_TIME_INCONSISTENCY_handler_get ( TALER_EC_GENERIC_DB_SETUP_FAILED, NULL); } - ja = json_array (); - GNUNET_break (NULL != ja); - - int64_t limit = -20; - uint64_t offset; - TALER_MHD_parse_request_snumber (connection, "limit", &limit); - if (limit < 0) offset = INT64_MAX; else offset = 0; - TALER_MHD_parse_request_number (connection, "offset", &offset); - - bool return_suppressed = false; - const char *ret_s = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "return_suppressed"); - if (ret_s != NULL && strcmp (ret_s, "true") == 0) { - return_suppressed = true; + const char *ret_s + = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "return_suppressed"); + if (ret_s != NULL && strcmp (ret_s, "true") == 0) + { + return_suppressed = true; + } } + ja = json_array (); + GNUNET_break (NULL != ja); qs = TAH_plugin->get_fee_time_inconsistency ( TAH_plugin->cls, limit, @@ -122,7 +117,6 @@ TAH_FEE_TIME_INCONSISTENCY_handler_get ( return_suppressed, &process_fee_time_inconsistency, ja); - if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); @@ -137,6 +131,6 @@ TAH_FEE_TIME_INCONSISTENCY_handler_get ( return TALER_MHD_REPLY_JSON_PACK ( connection, MHD_HTTP_OK, - GNUNET_JSON_pack_array_steal ("fee-time-inconsistency", + GNUNET_JSON_pack_array_steal ("fee_time_inconsistency", ja)); } diff --git a/src/auditor/taler-auditor-httpd_fee-time-inconsistency-upd.c b/src/auditor/taler-auditor-httpd_fee-time-inconsistency-upd.c deleted file mode 100644 index 3b4cea024..000000000 --- a/src/auditor/taler-auditor-httpd_fee-time-inconsistency-upd.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - 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 "platform.h" -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_json_lib.h> -#include <jansson.h> -#include <microhttpd.h> -#include <pthread.h> -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler-auditor-httpd.h" -#include "taler-auditor-httpd_fee-time-inconsistency-upd.h" - -MHD_RESULT -TAH_FEE_TIME_INCONSISTENCY_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - enum GNUNET_DB_QueryStatus qs; - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no row id specified"); - - - struct TALER_AUDITORDB_Generic_Update gu; - - gu.row_id = row_id; - - struct GNUNET_JSON_Specification spec[] = { - - // GNUNET_JSON_spec_uint64 ("row_id", &gu.row_id), - GNUNET_JSON_spec_bool ("suppressed", &gu.suppressed), - - GNUNET_JSON_spec_end () - }; - - json_t *json; - - (void) rh; - (void) connection_cls; - (void) upload_data; - (void) upload_data_size; - { - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_post_json (connection, - connection_cls, - upload_data, - upload_data_size, - &json); - if (GNUNET_SYSERR == res) - return MHD_NO; - if ((GNUNET_NO == res) || - (NULL == json)) - return MHD_YES; - res = TALER_MHD_parse_json_data (connection, - json, - spec); - if (GNUNET_SYSERR == res) - { - json_decref (json); - return MHD_NO; /* hard failure */ - } - if (GNUNET_NO == res) - { - json_decref (json); - return MHD_YES; /* failure */ - } - } - - /* execute transaction */ - qs = TAH_plugin->update_fee_time_inconsistency (TAH_plugin->cls, &gu); - - GNUNET_JSON_parse_free (spec); - json_decref (json); - - MHD_RESULT ret = MHD_NO; - - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "update_account"); - break; - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "unexpected serialization problem"); - break; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no updates executed"); - break; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - ret = TALER_MHD_reply_static (connection, - MHD_HTTP_NO_CONTENT, - NULL, - NULL, - 0); - break; - } - - return ret; -} diff --git a/src/auditor/taler-auditor-httpd_fee-time-inconsistency-upd.h b/src/auditor/taler-auditor-httpd_fee-time-inconsistency-upd.h deleted file mode 100644 index 04aa5c90d..000000000 --- a/src/auditor/taler-auditor-httpd_fee-time-inconsistency-upd.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_FEE_TIME_INCONSISTENCY_UPD_H -#define SRC_TALER_AUDITOR_HTTPD_FEE_TIME_INCONSISTENCY_UPD_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -MHD_RESULT -TAH_FEE_TIME_INCONSISTENCY_handler_update (struct TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif // SRC_TALER_AUDITOR_HTTPD_FEE_TIME_INCONSISTENCY_UPD_H diff --git a/src/auditor/taler-auditor-httpd_historic-denomination-revenue-get.c b/src/auditor/taler-auditor-httpd_historic-denomination-revenue-get.c index 544b97398..8af956dba 100644 --- a/src/auditor/taler-auditor-httpd_historic-denomination-revenue-get.c +++ b/src/auditor/taler-auditor-httpd_historic-denomination-revenue-get.c @@ -32,7 +32,10 @@ * * @param[in,out] cls a `json_t *` array to extend * @param serial_id location of the @a dc in the database - * @param dc struct of inconsistencies + * @param denom_pub_hash public key hash of the denomination + * @param revenue_timestamp when was the revenue effective + * @param revenue_balance how much in profit did we make from this denomination + * @param loss_balance how much loss did we make from this denomination * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating */ static enum GNUNET_GenericReturnValue diff --git a/src/auditor/taler-auditor-httpd_misattribution-in-inconsistency-del.c b/src/auditor/taler-auditor-httpd_misattribution-in-inconsistency-del.c deleted file mode 100644 index e6fe726fa..000000000 --- a/src/auditor/taler-auditor-httpd_misattribution-in-inconsistency-del.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - 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-auditor-httpd_misattribution-in-inconsistency-del.h" - - -MHD_RESULT -TAH_MISATTRIBUTION_IN_INCONSISTENCY_handler_delete (struct - TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - - enum GNUNET_DB_QueryStatus qs; - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - - // execute the transaction - qs = TAH_plugin->delete_misattribution_in_inconsistency (TAH_plugin->cls, - row_id); - - if (0 == qs) - { - // goes in here if there was an error with the transaction - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - TALER_LOG_WARNING ( - "Failed to handle DELETE /misattribution-in-inconsistency/ %s", - args[1]); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - } - - // on success? - return TALER_MHD_REPLY_JSON_PACK (connection, - MHD_HTTP_NO_CONTENT, - GNUNET_JSON_pack_string ("status", - "MISATTRIBUTION_IN_INCONSISTENCY_OK")); - -} diff --git a/src/auditor/taler-auditor-httpd_misattribution-in-inconsistency-del.h b/src/auditor/taler-auditor-httpd_misattribution-in-inconsistency-del.h deleted file mode 100644 index 57b86ecf7..000000000 --- a/src/auditor/taler-auditor-httpd_misattribution-in-inconsistency-del.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_MISATTRIBUTION_IN_INCONSISTENCY_DEL_H -#define SRC_TALER_AUDITOR_HTTPD_MISATTRIBUTION_IN_INCONSISTENCY_DEL_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -/** - * Initialize subsystem. - */ -void -TEAH_MISATTRIBUTION_IN_INCONSISTENCY_DELETE_init (void); - -/** - * Shut down subsystem. - */ -void -TEAH_MISATTRIBUTION_IN_INCONSISTENCY_DELETE_done (void); - -/** - * Handle a "/misattribution-in-inconsistency" request. Parses the JSON, and, if - * successful, checks the signatures and stores the result in the DB. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @param args NULL-terminated array of remaining parts of the URI broken up at '/' - * @return MHD result code - */ -MHD_RESULT -TAH_MISATTRIBUTION_IN_INCONSISTENCY_handler_delete ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - - -#endif diff --git a/src/auditor/taler-auditor-httpd_misattribution-in-inconsistency-get.c b/src/auditor/taler-auditor-httpd_misattribution-in-inconsistency-get.c index 7225be9aa..ae1d697cd 100644 --- a/src/auditor/taler-auditor-httpd_misattribution-in-inconsistency-get.c +++ b/src/auditor/taler-auditor-httpd_misattribution-in-inconsistency-get.c @@ -13,8 +13,6 @@ You should have 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 "platform.h" #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_json_lib.h> @@ -26,38 +24,37 @@ #include "taler-auditor-httpd.h" #include "taler-auditor-httpd_misattribution-in-inconsistency-get.h" + /** -* Add misattribution-in-inconsistency to the list. -* -* @param[in,out] cls a `json_t *` array to extend -* @param serial_id location of the @a dc in the database -* @param dc struct of inconsistencies -* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating -*/ + * Add misattribution-in-inconsistency to the list. + * + * @param[in,out] cls a `json_t *` array to extend + * @param dc struct of inconsistencies + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ static enum GNUNET_GenericReturnValue process_misattribution_in_inconsistency ( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_MisattributionInInconsistency *dc) { json_t *list = cls; json_t *obj; obj = GNUNET_JSON_PACK ( - - GNUNET_JSON_pack_int64 ("row_id", serial_id), - TALER_JSON_pack_amount ("amount", &dc->amount), - GNUNET_JSON_pack_int64 ("bank_row", dc->bank_row), - GNUNET_JSON_pack_data_auto ("reserve_pub", &dc->reserve_pub), - GNUNET_JSON_pack_bool ("suppressed", dc->suppressed) - - + GNUNET_JSON_pack_uint64 ("row_id", + dc->row_id), + TALER_JSON_pack_amount ("amount", + &dc->amount), + GNUNET_JSON_pack_uint64 ("bank_row", + dc->bank_row), + GNUNET_JSON_pack_data_auto ("reserve_pub", + &dc->reserve_pub), + GNUNET_JSON_pack_bool ("suppressed", + dc->suppressed) ); GNUNET_break (0 == json_array_append_new (list, obj)); - - return GNUNET_OK; } @@ -73,6 +70,9 @@ TAH_MISATTRIBUTION_IN_INCONSISTENCY_handler_get ( { json_t *ja; enum GNUNET_DB_QueryStatus qs; + int64_t limit = -20; + uint64_t offset; + bool return_suppressed = false; (void) rh; (void) connection_cls; @@ -87,34 +87,29 @@ TAH_MISATTRIBUTION_IN_INCONSISTENCY_handler_get ( TALER_EC_GENERIC_DB_SETUP_FAILED, NULL); } - ja = json_array (); - GNUNET_break (NULL != ja); - - int64_t limit = -20; - uint64_t offset; - TALER_MHD_parse_request_snumber (connection, "limit", &limit); - if (limit < 0) offset = INT64_MAX; else offset = 0; - TALER_MHD_parse_request_number (connection, "offset", &offset); - - bool return_suppressed = false; - const char *ret_s = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "return_suppressed"); - if (ret_s != NULL && strcmp (ret_s, "true") == 0) { - return_suppressed = true; + const char *ret_s + = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "return_suppressed"); + if (ret_s != NULL && strcmp (ret_s, "true") == 0) + { + return_suppressed = true; + } } + ja = json_array (); + GNUNET_break (NULL != ja); qs = TAH_plugin->get_misattribution_in_inconsistency ( TAH_plugin->cls, limit, @@ -122,7 +117,6 @@ TAH_MISATTRIBUTION_IN_INCONSISTENCY_handler_get ( return_suppressed, &process_misattribution_in_inconsistency, ja); - if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); @@ -137,6 +131,6 @@ TAH_MISATTRIBUTION_IN_INCONSISTENCY_handler_get ( return TALER_MHD_REPLY_JSON_PACK ( connection, MHD_HTTP_OK, - GNUNET_JSON_pack_array_steal ("misattribution-in-inconsistency", + GNUNET_JSON_pack_array_steal ("misattribution_in_inconsistency", ja)); } diff --git a/src/auditor/taler-auditor-httpd_misattribution-in-inconsistency-upd.c b/src/auditor/taler-auditor-httpd_misattribution-in-inconsistency-upd.c deleted file mode 100644 index 3a2a7cdd3..000000000 --- a/src/auditor/taler-auditor-httpd_misattribution-in-inconsistency-upd.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - 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 "platform.h" -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_json_lib.h> -#include <jansson.h> -#include <microhttpd.h> -#include <pthread.h> -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler-auditor-httpd.h" -#include "taler-auditor-httpd_misattribution-in-inconsistency-upd.h" - -MHD_RESULT -TAH_MISATTRIBUTION_IN_INCONSISTENCY_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - enum GNUNET_DB_QueryStatus qs; - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no row id specified"); - - - struct TALER_AUDITORDB_Generic_Update gu; - - gu.row_id = row_id; - - struct GNUNET_JSON_Specification spec[] = { - - // GNUNET_JSON_spec_uint64 ("row_id", &gu.row_id), - GNUNET_JSON_spec_bool ("suppressed", &gu.suppressed), - - GNUNET_JSON_spec_end () - }; - - json_t *json; - - (void) rh; - (void) connection_cls; - (void) upload_data; - (void) upload_data_size; - { - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_post_json (connection, - connection_cls, - upload_data, - upload_data_size, - &json); - if (GNUNET_SYSERR == res) - return MHD_NO; - if ((GNUNET_NO == res) || - (NULL == json)) - return MHD_YES; - res = TALER_MHD_parse_json_data (connection, - json, - spec); - if (GNUNET_SYSERR == res) - { - json_decref (json); - return MHD_NO; /* hard failure */ - } - if (GNUNET_NO == res) - { - json_decref (json); - return MHD_YES; /* failure */ - } - } - - /* execute transaction */ - qs = TAH_plugin->update_misattribution_in_inconsistency (TAH_plugin->cls, - &gu); - - GNUNET_JSON_parse_free (spec); - json_decref (json); - - MHD_RESULT ret = MHD_NO; - - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "update_account"); - break; - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "unexpected serialization problem"); - break; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no updates executed"); - break; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - ret = TALER_MHD_reply_static (connection, - MHD_HTTP_NO_CONTENT, - NULL, - NULL, - 0); - break; - } - - return ret; -} diff --git a/src/auditor/taler-auditor-httpd_misattribution-in-inconsistency-upd.h b/src/auditor/taler-auditor-httpd_misattribution-in-inconsistency-upd.h deleted file mode 100644 index 966c5e1d7..000000000 --- a/src/auditor/taler-auditor-httpd_misattribution-in-inconsistency-upd.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_MISATTRIBUTION_IN_INCONSISTENCY_UPD_H -#define SRC_TALER_AUDITOR_HTTPD_MISATTRIBUTION_IN_INCONSISTENCY_UPD_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -MHD_RESULT -TAH_MISATTRIBUTION_IN_INCONSISTENCY_handler_update (struct - TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif // SRC_TALER_AUDITOR_HTTPD_MISATTRIBUTION_IN_INCONSISTENCY_UPD_H diff --git a/src/auditor/taler-auditor-httpd_patch_generic_suppressed.c b/src/auditor/taler-auditor-httpd_patch_generic_suppressed.c index f58635c5b..841f7a824 100644 --- a/src/auditor/taler-auditor-httpd_patch_generic_suppressed.c +++ b/src/auditor/taler-auditor-httpd_patch_generic_suppressed.c @@ -13,8 +13,6 @@ You should have 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 "platform.h" #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_json_lib.h> @@ -24,7 +22,7 @@ #include "taler_json_lib.h" #include "taler_mhd_lib.h" #include "taler-auditor-httpd.h" -#include "taler-auditor-httpd_amount-arithmetic-inconsistency-upd.h" +#include "taler-auditor-httpd_patch_generic_suppressed.h" MHD_RESULT diff --git a/src/auditor/taler-auditor-httpd_progress-get.c b/src/auditor/taler-auditor-httpd_progress-get.c index 06933e53c..06bc69124 100644 --- a/src/auditor/taler-auditor-httpd_progress-get.c +++ b/src/auditor/taler-auditor-httpd_progress-get.c @@ -24,34 +24,31 @@ #include "taler-auditor-httpd.h" #include "taler-auditor-httpd_progress-get.h" + /** * Add progress to the list. * * @param[in,out] cls a `json_t *` array to extend - * @param serial_id location of the @a dc in the database - * @param dc struct of inconsistencies + * @param dc struct with progress data * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating */ static enum GNUNET_GenericReturnValue process_progress ( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_Progress *dc) { json_t *list = cls; json_t *obj; obj = GNUNET_JSON_PACK ( - - GNUNET_JSON_pack_string ("progress_key", dc->progress_key), - GNUNET_JSON_pack_int64 ("progress_offset", dc->progress_offset) - + GNUNET_JSON_pack_string ("progress_key", + dc->progress_key), + GNUNET_JSON_pack_int64 ("progress_offset", + dc->progress_offset) ); GNUNET_break (0 == json_array_append_new (list, obj)); - - return GNUNET_OK; } @@ -67,6 +64,7 @@ TAH_PROGRESS_handler_get ( { json_t *ja; enum GNUNET_DB_QueryStatus qs; + const char *progress_key; (void) rh; (void) connection_cls; @@ -81,42 +79,21 @@ TAH_PROGRESS_handler_get ( TALER_EC_GENERIC_DB_SETUP_FAILED, NULL); } + progress_key + = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "progress_key"); ja = json_array (); GNUNET_break (NULL != ja); - - int64_t limit = -20; - uint64_t offset; - - TALER_MHD_parse_request_snumber (connection, - "limit", - &limit); - - if (limit < 0) - offset = INT64_MAX; - else - offset = 0; - - TALER_MHD_parse_request_number (connection, - "offset", - &offset); - - bool return_suppressed = false; - - - qs = TAH_plugin->get_progress ( + qs = TAH_plugin->get_progress_points ( TAH_plugin->cls, - limit, - offset, - return_suppressed, + progress_key, &process_progress, ja); - if (0 > qs) { - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); + GNUNET_break (0); json_decref (ja); - TALER_LOG_WARNING ( - "Failed to handle GET /progress\n"); return TALER_MHD_reply_with_error (connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_GENERIC_DB_FETCH_FAILED, diff --git a/src/auditor/taler-auditor-httpd_progress-get.h b/src/auditor/taler-auditor-httpd_progress-get.h index 0a3d6b9c5..46d38846d 100644 --- a/src/auditor/taler-auditor-httpd_progress-get.h +++ b/src/auditor/taler-auditor-httpd_progress-get.h @@ -13,37 +13,14 @@ You should have 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 SRC_TALER_AUDITOR_HTTPD_PROGRESS_GET_H -#define SRC_TALER_AUDITOR_HTTPD_PROGRESS_GET_H +#ifndef TALER_AUDITOR_HTTPD_PROGRESS_GET_H +#define TALER_AUDITOR_HTTPD_PROGRESS_GET_H #include <gnunet/gnunet_util_lib.h> #include <microhttpd.h> #include "taler-auditor-httpd.h" -/** -* Initialize subsystem. -*/ -void -TEAH_PROGRESS_GET_init (void); -/** -* Shut down subsystem. -*/ -void -TEAH_PROGRESS_GET_done (void); - -/** - * Handle a "/progress" request. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @param args NULL-terminated array of remaining parts of the URI broken up at '/' - * @return MHD result code - */ -// FIXME: very bad name! MHD_RESULT TAH_PROGRESS_handler_get ( struct TAH_RequestHandler *rh, @@ -53,5 +30,4 @@ TAH_PROGRESS_handler_get ( size_t *upload_data_size, const char *const args[]); - #endif diff --git a/src/auditor/taler-auditor-httpd_progress-put.c b/src/auditor/taler-auditor-httpd_progress-put.c deleted file mode 100644 index 67f19f150..000000000 --- a/src/auditor/taler-auditor-httpd_progress-put.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - 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 "platform.h" -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_json_lib.h> -#include <jansson.h> -#include <microhttpd.h> -#include <pthread.h> -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler-auditor-httpd.h" -#include "taler-auditor-httpd_progress-put.h" - -/** -* We have parsed the JSON information about the progress, do some -* basic sanity checks and then execute the -* transaction. -* -* @param connection the MHD connection to handle -* @param dc information about the progress -* @return MHD result code -*/ -static MHD_RESULT -process_inconsistency ( - struct MHD_Connection *connection, - const struct TALER_AUDITORDB_Progress *dc) -{ - - enum GNUNET_DB_QueryStatus qs; - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - /* execute transaction */ - qs = TAH_plugin->insert_progress (TAH_plugin->cls, - dc); - if (0 > qs) - { - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - TALER_LOG_WARNING ( - "Failed to store /progress in database\n"); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "progress"); - } - return TALER_MHD_REPLY_JSON_PACK (connection, - MHD_HTTP_OK, - GNUNET_JSON_pack_string ("status", - "PROGRESS_OK")); -} - - -MHD_RESULT -TAH_PROGRESS_PUT_handler ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - - struct TALER_AUDITORDB_Progress dc; - - - struct GNUNET_JSON_Specification spec[] = { - - GNUNET_JSON_spec_string ("progress_key", (const char **) &dc.progress_key), - GNUNET_JSON_spec_string ("progress_offset", (const - char **) &dc.progress_offset), - - - GNUNET_JSON_spec_end () - }; - - - json_t *json; - - (void) rh; - (void) connection_cls; - (void) upload_data; - (void) upload_data_size; - { - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_post_json (connection, - connection_cls, - upload_data, - upload_data_size, - &json); - if (GNUNET_SYSERR == res) - return MHD_NO; - if ((GNUNET_NO == res) || - (NULL == json)) - return MHD_YES; - res = TALER_MHD_parse_json_data (connection, - json, - spec); - if (GNUNET_SYSERR == res) - { - json_decref (json); - return MHD_NO; /* hard failure */ - } - if (GNUNET_NO == res) - { - json_decref (json); - return MHD_YES; /* failure */ - } - } - - MHD_RESULT res; - - res = process_inconsistency (connection, &dc); - GNUNET_JSON_parse_free (spec); - - json_decref (json); - return res; - -} - - -void -TEAH_PROGRESS_PUT_init (void) -{ - -} - - -void -TEAH_PROGRESS_PUT_done (void) -{ - -} diff --git a/src/auditor/taler-auditor-httpd_progress-put.h b/src/auditor/taler-auditor-httpd_progress-put.h deleted file mode 100644 index d7e3db0b3..000000000 --- a/src/auditor/taler-auditor-httpd_progress-put.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_PROGRESS_PUT_H -#define SRC_TALER_AUDITOR_HTTPD_PROGRESS_PUT_H - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -/** -* Initialize subsystem. -*/ -void -TEAH_PROGRESS_PUT_init (void); - -/** -* Shut down subsystem. -*/ -void -TEAH_PROGRESS_PUT_done (void); - - -/** - * Handle a "/progress" request. Parses the JSON, and, if - * successful, checks the signatures and stores the result in the DB. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @param args NULL-terminated array of remaining parts of the URI broken up at '/' - * @return MHD result code - */ -MHD_RESULT -TAH_PROGRESS_PUT_handler ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - - -#endif diff --git a/src/auditor/taler-auditor-httpd_purse-not-closed-inconsistencies-del.c b/src/auditor/taler-auditor-httpd_purse-not-closed-inconsistencies-del.c deleted file mode 100644 index 0310e9b52..000000000 --- a/src/auditor/taler-auditor-httpd_purse-not-closed-inconsistencies-del.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - 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-auditor-httpd_purse-not-closed-inconsistencies-del.h" - - -MHD_RESULT -TAH_PURSE_NOT_CLOSED_INCONSISTENCIES_handler_delete (struct - TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - - enum GNUNET_DB_QueryStatus qs; - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - - // execute the transaction - qs = TAH_plugin->delete_purse_not_closed_inconsistencies (TAH_plugin->cls, - row_id); - - if (0 > qs) - { - // goes in here if there was an error with the transaction - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - TALER_LOG_WARNING ( - "Failed to handle DELETE /purse-not-closed-inconsistencies/ %s\n", - args[1]); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - } - - // on success? - return TALER_MHD_REPLY_JSON_PACK (connection, - MHD_HTTP_NO_CONTENT, - GNUNET_JSON_pack_string ("status", - "PURSE_NOT_CLOSED_INCONSISTENCIES_OK")); - -} diff --git a/src/auditor/taler-auditor-httpd_purse-not-closed-inconsistencies-del.h b/src/auditor/taler-auditor-httpd_purse-not-closed-inconsistencies-del.h deleted file mode 100644 index 620a55aa1..000000000 --- a/src/auditor/taler-auditor-httpd_purse-not-closed-inconsistencies-del.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_PURSE_NOT_CLOSED_INCONSISTENCIES_DEL_H -#define SRC_TALER_AUDITOR_HTTPD_PURSE_NOT_CLOSED_INCONSISTENCIES_DEL_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -/** -* Initialize subsystem. -*/ -void -TEAH_PURSE_NOT_CLOSED_INCONSISTENCIES_DELETE_init (void); - -/** -* Shut down subsystem. -*/ -void -TEAH_PURSE_NOT_CLOSED_INCONSISTENCIES_DELETE_done (void); - -/** - * Handle a "/purse-not-closed-inconsistencies" request. Parses the JSON, and, if - * successful, checks the signatures and stores the result in the DB. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @param args NULL-terminated array of remaining parts of the URI broken up at '/' - * @return MHD result code - */ -MHD_RESULT -TAH_PURSE_NOT_CLOSED_INCONSISTENCIES_handler_delete ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif diff --git a/src/auditor/taler-auditor-httpd_purse-not-closed-inconsistencies-get.c b/src/auditor/taler-auditor-httpd_purse-not-closed-inconsistencies-get.c index 2d06456c1..58421caa4 100644 --- a/src/auditor/taler-auditor-httpd_purse-not-closed-inconsistencies-get.c +++ b/src/auditor/taler-auditor-httpd_purse-not-closed-inconsistencies-get.c @@ -13,8 +13,6 @@ You should have 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 "platform.h" #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_json_lib.h> @@ -30,32 +28,32 @@ * Add purse-not-closed-inconsistencies to the list. * * @param[in,out] cls a `json_t *` array to extend - * @param serial_id location of the @a dc in the database * @param dc struct of inconsistencies * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating */ static enum GNUNET_GenericReturnValue process_purse_not_closed_inconsistencies ( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_PurseNotClosedInconsistencies *dc) { json_t *list = cls; json_t *obj; obj = GNUNET_JSON_PACK ( - - GNUNET_JSON_pack_data_auto ("purse_pub", &dc->purse_pub), - TALER_JSON_pack_amount ("amount", &dc->amount), - TALER_JSON_pack_time_abs_human ("expiration_date", dc->expiration_date) - - + GNUNET_JSON_pack_uint64 ("row_id", + dc->row_id), + GNUNET_JSON_pack_data_auto ("purse_pub", + &dc->purse_pub), + TALER_JSON_pack_amount ("amount", + &dc->amount), + TALER_JSON_pack_time_abs_human ("expiration_date", + dc->expiration_date), + GNUNET_JSON_pack_bool ("suppressed", + dc->suppressed) ); GNUNET_break (0 == json_array_append_new (list, obj)); - - return GNUNET_OK; } @@ -71,6 +69,9 @@ TAH_PURSE_NOT_CLOSED_INCONSISTENCIES_handler_get ( { json_t *ja; enum GNUNET_DB_QueryStatus qs; + int64_t limit = -20; + uint64_t offset; + bool return_suppressed = false; (void) rh; (void) connection_cls; @@ -85,28 +86,33 @@ TAH_PURSE_NOT_CLOSED_INCONSISTENCIES_handler_get ( TALER_EC_GENERIC_DB_SETUP_FAILED, NULL); } - ja = json_array (); - GNUNET_break (NULL != ja); - - int64_t limit = -20; - uint64_t offset; - TALER_MHD_parse_request_snumber (connection, "limit", &limit); - if (limit < 0) offset = INT64_MAX; else offset = 0; - TALER_MHD_parse_request_number (connection, "offset", &offset); - bool return_suppressed = false; - + { + const char *ret_s + = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "return_suppressed"); + + if ( (NULL != ret_s) && + (0 == strcmp (ret_s, + "true")) ) + { + return_suppressed = true; + } + } + ja = json_array (); + GNUNET_break (NULL != ja); qs = TAH_plugin->get_purse_not_closed_inconsistencies ( TAH_plugin->cls, limit, @@ -129,6 +135,6 @@ TAH_PURSE_NOT_CLOSED_INCONSISTENCIES_handler_get ( return TALER_MHD_REPLY_JSON_PACK ( connection, MHD_HTTP_OK, - GNUNET_JSON_pack_array_steal ("purse-not-closed-inconsistencies", + GNUNET_JSON_pack_array_steal ("purse_not_closed_inconsistencies", ja)); } diff --git a/src/auditor/taler-auditor-httpd_purse-not-closed-inconsistencies-upd.c b/src/auditor/taler-auditor-httpd_purse-not-closed-inconsistencies-upd.c deleted file mode 100644 index 10024be5e..000000000 --- a/src/auditor/taler-auditor-httpd_purse-not-closed-inconsistencies-upd.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - 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 "platform.h" -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_json_lib.h> -#include <jansson.h> -#include <microhttpd.h> -#include <pthread.h> -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler-auditor-httpd.h" -#include "taler-auditor-httpd_purse-not-closed-inconsistencies-upd.h" - -MHD_RESULT -TAH_PURSE_NOT_CLOSED_INCONSISTENCIES_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - enum GNUNET_DB_QueryStatus qs; - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no row id specified"); - - - struct TALER_AUDITORDB_Generic_Update gu; - - gu.row_id = row_id; - - struct GNUNET_JSON_Specification spec[] = { - - // GNUNET_JSON_spec_uint64 ("row_id", &gu.row_id), - GNUNET_JSON_spec_bool ("suppressed", &gu.suppressed), - - GNUNET_JSON_spec_end () - }; - - json_t *json; - - (void) rh; - (void) connection_cls; - (void) upload_data; - (void) upload_data_size; - { - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_post_json (connection, - connection_cls, - upload_data, - upload_data_size, - &json); - if (GNUNET_SYSERR == res) - return MHD_NO; - if ((GNUNET_NO == res) || - (NULL == json)) - return MHD_YES; - res = TALER_MHD_parse_json_data (connection, - json, - spec); - if (GNUNET_SYSERR == res) - { - json_decref (json); - return MHD_NO; /* hard failure */ - } - if (GNUNET_NO == res) - { - json_decref (json); - return MHD_YES; /* failure */ - } - } - - /* execute transaction */ - qs = TAH_plugin->update_purse_not_closed_inconsistencies (TAH_plugin->cls, - &gu); - - GNUNET_JSON_parse_free (spec); - json_decref (json); - - MHD_RESULT ret = MHD_NO; - - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "update_account"); - break; - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "unexpected serialization problem"); - break; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no updates executed"); - break; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - ret = TALER_MHD_reply_static (connection, - MHD_HTTP_NO_CONTENT, - NULL, - NULL, - 0); - break; - } - - return ret; -} diff --git a/src/auditor/taler-auditor-httpd_purse-not-closed-inconsistencies-upd.h b/src/auditor/taler-auditor-httpd_purse-not-closed-inconsistencies-upd.h deleted file mode 100644 index cd0b3f602..000000000 --- a/src/auditor/taler-auditor-httpd_purse-not-closed-inconsistencies-upd.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_PURSE_NOT_CLOSED_INCONSISTENCIES_UPD_H -#define SRC_TALER_AUDITOR_HTTPD_PURSE_NOT_CLOSED_INCONSISTENCIES_UPD_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -MHD_RESULT -TAH_PURSE_NOT_CLOSED_INCONSISTENCIES_handler_update (struct - TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif // SRC_TALER_AUDITOR_HTTPD_PURSE_NOT_CLOSED_INCONSISTENCIES_UPD_H diff --git a/src/auditor/taler-auditor-httpd_purses-get.c b/src/auditor/taler-auditor-httpd_purses-get.c index a581f62d3..579521b73 100644 --- a/src/auditor/taler-auditor-httpd_purses-get.c +++ b/src/auditor/taler-auditor-httpd_purses-get.c @@ -73,6 +73,8 @@ TAH_PURSES_handler_get ( { json_t *ja; enum GNUNET_DB_QueryStatus qs; + int64_t limit = -20; + uint64_t offset; (void) rh; (void) connection_cls; @@ -82,41 +84,30 @@ TAH_PURSES_handler_get ( TAH_plugin->preflight (TAH_plugin->cls)) { GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); + return TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_SETUP_FAILED, + NULL); } - ja = json_array (); - GNUNET_break (NULL != ja); - - int64_t limit = -20; - uint64_t offset; - TALER_MHD_parse_request_snumber (connection, "limit", &limit); - if (limit < 0) offset = INT64_MAX; else offset = 0; - TALER_MHD_parse_request_number (connection, "offset", &offset); - - bool return_suppressed = false; - - + ja = json_array (); + GNUNET_break (NULL != ja); qs = TAH_plugin->get_purses ( TAH_plugin->cls, limit, offset, - return_suppressed, &process_purses, ja); - if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); diff --git a/src/auditor/taler-auditor-httpd_refreshes-hanging-del.c b/src/auditor/taler-auditor-httpd_refreshes-hanging-del.c deleted file mode 100644 index bbe1e8e2c..000000000 --- a/src/auditor/taler-auditor-httpd_refreshes-hanging-del.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - 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-auditor-httpd_refreshes-hanging-del.h" - - -MHD_RESULT -TAH_REFRESHES_HANGING_handler_delete (struct TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - - - enum GNUNET_DB_QueryStatus qs; - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - - // execute the transaction - qs = TAH_plugin->delete_refreshes_hanging (TAH_plugin->cls, - row_id); - - if (0 > qs) - { - // goes in here if there was an error with the transaction - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - TALER_LOG_WARNING ( - "Failed to handle DELETE /refreshes-hanging/ %s\n", - args[1]); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - } - - // on success? - return TALER_MHD_REPLY_JSON_PACK (connection, - MHD_HTTP_NO_CONTENT, - GNUNET_JSON_pack_string ("status", - "REFRESHES_HANGING_OK")); - - -} diff --git a/src/auditor/taler-auditor-httpd_refreshes-hanging-del.h b/src/auditor/taler-auditor-httpd_refreshes-hanging-del.h deleted file mode 100644 index b1a4f0cbf..000000000 --- a/src/auditor/taler-auditor-httpd_refreshes-hanging-del.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_REFRESHES_HANGING_DEL_H -#define SRC_TALER_AUDITOR_HTTPD_REFRESHES_HANGING_DEL_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -/** -* Initialize subsystem. -*/ -void -TEAH_REFRESHES_HANGING_DELETE_init (void); - -/** -* Shut down subsystem. -*/ -void -TEAH_REFRESHES_HANGING_DELETE_done (void); - -/** - * Handle a "/refreshes-hanging" request. Parses the JSON, and, if - * successful, checks the signatures and stores the result in the DB. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @param args NULL-terminated array of remaining parts of the URI broken up at '/' - * @return MHD result code - */ -MHD_RESULT -TAH_REFRESHES_HANGING_handler_delete ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif diff --git a/src/auditor/taler-auditor-httpd_refreshes-hanging-get.c b/src/auditor/taler-auditor-httpd_refreshes-hanging-get.c index 50a308517..4a4da1c4e 100644 --- a/src/auditor/taler-auditor-httpd_refreshes-hanging-get.c +++ b/src/auditor/taler-auditor-httpd_refreshes-hanging-get.c @@ -13,8 +13,6 @@ You should have 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 "platform.h" #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_json_lib.h> @@ -26,34 +24,33 @@ #include "taler-auditor-httpd.h" #include "taler-auditor-httpd_refreshes-hanging-get.h" + /** * Add refreshes-hanging to the list. * * @param[in,out] cls a `json_t *` array to extend - * @param serial_id location of the @a dc in the database * @param dc struct of inconsistencies * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating */ static enum GNUNET_GenericReturnValue process_refreshes_hanging ( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_RefreshesHanging *dc) { json_t *list = cls; json_t *obj; obj = GNUNET_JSON_PACK ( - - TALER_JSON_pack_amount ("amount", &dc->amount), - GNUNET_JSON_pack_data_auto ("coin_pub", &dc->coin_pub) - + TALER_JSON_pack_amount ("amount", + &dc->amount), + GNUNET_JSON_pack_uint64 ("serial_id", + dc->row_id), + GNUNET_JSON_pack_uint64 ("problem_row", + dc->problem_row_id) ); GNUNET_break (0 == json_array_append_new (list, obj)); - - return GNUNET_OK; } @@ -69,6 +66,9 @@ TAH_REFRESHES_HANGING_handler_get ( { json_t *ja; enum GNUNET_DB_QueryStatus qs; + int64_t limit = -20; + uint64_t offset; + bool return_suppressed = false; (void) rh; (void) connection_cls; @@ -83,34 +83,31 @@ TAH_REFRESHES_HANGING_handler_get ( TALER_EC_GENERIC_DB_SETUP_FAILED, NULL); } - ja = json_array (); - GNUNET_break (NULL != ja); - - int64_t limit = -20; - uint64_t offset; - TALER_MHD_parse_request_snumber (connection, "limit", &limit); - if (limit < 0) offset = INT64_MAX; else offset = 0; - TALER_MHD_parse_request_number (connection, "offset", &offset); - - bool return_suppressed = false; - const char *ret_s = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "return_suppressed"); - if (ret_s != NULL && strcmp (ret_s, "true") == 0) { - return_suppressed = true; + const char *ret_s + = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "return_suppressed"); + + if ( (NULL != ret_s) && + (0 == strcmp (ret_s, + "true")) ) + { + return_suppressed = true; + } } - + ja = json_array (); + GNUNET_break (NULL != ja); qs = TAH_plugin->get_refreshes_hanging ( TAH_plugin->cls, limit, @@ -118,7 +115,6 @@ TAH_REFRESHES_HANGING_handler_get ( return_suppressed, &process_refreshes_hanging, ja); - if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); diff --git a/src/auditor/taler-auditor-httpd_refreshes-hanging-upd.c b/src/auditor/taler-auditor-httpd_refreshes-hanging-upd.c deleted file mode 100644 index edcb3b7a3..000000000 --- a/src/auditor/taler-auditor-httpd_refreshes-hanging-upd.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - 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 "platform.h" -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_json_lib.h> -#include <jansson.h> -#include <microhttpd.h> -#include <pthread.h> -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler-auditor-httpd.h" -#include "taler-auditor-httpd_refreshes-hanging-upd.h" - -MHD_RESULT -TAH_REFRESHES_HANGING_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - enum GNUNET_DB_QueryStatus qs; - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no row id specified"); - - - struct TALER_AUDITORDB_Generic_Update gu; - - gu.row_id = row_id; - - struct GNUNET_JSON_Specification spec[] = { - - // GNUNET_JSON_spec_uint64 ("row_id", &gu.row_id), - GNUNET_JSON_spec_bool ("suppressed", &gu.suppressed), - - GNUNET_JSON_spec_end () - }; - - json_t *json; - - (void) rh; - (void) connection_cls; - (void) upload_data; - (void) upload_data_size; - { - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_post_json (connection, - connection_cls, - upload_data, - upload_data_size, - &json); - if (GNUNET_SYSERR == res) - return MHD_NO; - if ((GNUNET_NO == res) || - (NULL == json)) - return MHD_YES; - res = TALER_MHD_parse_json_data (connection, - json, - spec); - if (GNUNET_SYSERR == res) - { - json_decref (json); - return MHD_NO; /* hard failure */ - } - if (GNUNET_NO == res) - { - json_decref (json); - return MHD_YES; /* failure */ - } - } - - /* execute transaction */ - qs = TAH_plugin->update_refreshes_hanging (TAH_plugin->cls, &gu); - - GNUNET_JSON_parse_free (spec); - json_decref (json); - - MHD_RESULT ret = MHD_NO; - - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "update_account"); - break; - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "unexpected serialization problem"); - break; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no updates executed"); - break; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - ret = TALER_MHD_reply_static (connection, - MHD_HTTP_NO_CONTENT, - NULL, - NULL, - 0); - break; - } - - return ret; -} diff --git a/src/auditor/taler-auditor-httpd_refreshes-hanging-upd.h b/src/auditor/taler-auditor-httpd_refreshes-hanging-upd.h deleted file mode 100644 index ffc241c55..000000000 --- a/src/auditor/taler-auditor-httpd_refreshes-hanging-upd.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_REFRESHES_HANGING_UPD_H -#define SRC_TALER_AUDITOR_HTTPD_REFRESHES_HANGING_UPD_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -MHD_RESULT -TAH_REFRESHES_HANGING_handler_update (struct TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif // SRC_TALER_AUDITOR_HTTPD_REFRESHES_HANGING_UPD_H diff --git a/src/auditor/taler-auditor-httpd_reserve-balance-insufficient-inconsistency-del.c b/src/auditor/taler-auditor-httpd_reserve-balance-insufficient-inconsistency-del.c deleted file mode 100644 index 29acb4249..000000000 --- a/src/auditor/taler-auditor-httpd_reserve-balance-insufficient-inconsistency-del.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - 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-auditor-httpd_reserve-balance-insufficient-inconsistency-del.h" - - -MHD_RESULT -TAH_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_handler_delete (struct - TAH_RequestHandler - *rh, - struct - MHD_Connection * - connection, - void ** - connection_cls, - const char * - upload_data, - size_t * - upload_data_size, - const char *const - args[]) -{ - - enum GNUNET_DB_QueryStatus qs; - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - - // execute the transaction - qs = TAH_plugin->delete_reserve_balance_insufficient_inconsistency ( - TAH_plugin->cls, - row_id); - - if (0 == qs) - { - // goes in here if there was an error with the transaction - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - TALER_LOG_WARNING ( - "Failed to handle DELETE /reserve-balance-insufficient-inconsistency/ %s\n", - args[1]); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - } - - // on success? - return TALER_MHD_REPLY_JSON_PACK (connection, - MHD_HTTP_NO_CONTENT, - GNUNET_JSON_pack_string ("status", - "RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_OK")); - -} diff --git a/src/auditor/taler-auditor-httpd_reserve-balance-insufficient-inconsistency-del.h b/src/auditor/taler-auditor-httpd_reserve-balance-insufficient-inconsistency-del.h deleted file mode 100644 index 42937e4b2..000000000 --- a/src/auditor/taler-auditor-httpd_reserve-balance-insufficient-inconsistency-del.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - 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 TALER_AUDITOR_HTTPD_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_DEL_H -#define TALER_AUDITOR_HTTPD_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_DEL_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -/** -* Initialize subsystem. -*/ -void -TEAH_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_DELETE_init (void); - -/** - * Shut down subsystem. - */ -void -TEAH_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_DELETE_done (void); - -/** - * Handle a "/reserve-balance-insufficient-inconsistency" request. Parses the JSON, and, if - * successful, checks the signatures and stores the result in the DB. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @param args NULL-terminated array of remaining parts of the URI broken up at '/' - * @return MHD result code - */ -MHD_RESULT -TAH_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_handler_delete ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif diff --git a/src/auditor/taler-auditor-httpd_reserve-balance-insufficient-inconsistency-get.c b/src/auditor/taler-auditor-httpd_reserve-balance-insufficient-inconsistency-get.c index 87025b434..5f3d66c63 100644 --- a/src/auditor/taler-auditor-httpd_reserve-balance-insufficient-inconsistency-get.c +++ b/src/auditor/taler-auditor-httpd_reserve-balance-insufficient-inconsistency-get.c @@ -13,8 +13,6 @@ You should have 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 "platform.h" #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_json_lib.h> @@ -26,36 +24,37 @@ #include "taler-auditor-httpd.h" #include "taler-auditor-httpd_reserve-balance-insufficient-inconsistency-get.h" + /** -* Add reserve-balance-insufficient-inconsistency to the list. -* -* @param[in,out] cls a `json_t *` array to extend -* @param serial_id location of the @a dc in the database -* @param dc struct of inconsistencies -* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating -*/ + * Add reserve-balance-insufficient-inconsistency to the list. + * + * @param[in,out] cls a `json_t *` array to extend + * @param dc struct of inconsistencies + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ static enum GNUNET_GenericReturnValue process_reserve_balance_insufficient_inconsistency ( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_ReserveBalanceInsufficientInconsistency *dc) { json_t *list = cls; json_t *obj; obj = GNUNET_JSON_PACK ( - - GNUNET_JSON_pack_uint64 ("row_id", serial_id), - GNUNET_JSON_pack_data_auto ("reserve_pub", &dc->reserve_pub), - GNUNET_JSON_pack_bool ("inconsistency_gain", dc->inconsistency_gain), - TALER_JSON_pack_amount ("inconsistency_amount", &dc->inconsistency_amount) - + GNUNET_JSON_pack_uint64 ("row_id", + dc->row_id), + GNUNET_JSON_pack_data_auto ("reserve_pub", + &dc->reserve_pub), + GNUNET_JSON_pack_bool ("inconsistency_gain", + dc->inconsistency_gain), + TALER_JSON_pack_amount ("inconsistency_amount", + &dc->inconsistency_amount), + GNUNET_JSON_pack_bool ("suppressed", + dc->suppressed) ); GNUNET_break (0 == json_array_append_new (list, obj)); - - return GNUNET_OK; } @@ -71,6 +70,9 @@ TAH_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_handler_get ( { json_t *ja; enum GNUNET_DB_QueryStatus qs; + int64_t limit = -20; + uint64_t offset; + bool return_suppressed = false; (void) rh; (void) connection_cls; @@ -85,33 +87,29 @@ TAH_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_handler_get ( TALER_EC_GENERIC_DB_SETUP_FAILED, NULL); } - ja = json_array (); - GNUNET_break (NULL != ja); - - int64_t limit = -20; - uint64_t offset; - TALER_MHD_parse_request_snumber (connection, "limit", &limit); - if (limit < 0) offset = INT64_MAX; else offset = 0; - TALER_MHD_parse_request_number (connection, "offset", &offset); - bool return_suppressed = false; - const char *ret_s = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "return_suppressed"); - if (ret_s != NULL && strcmp (ret_s, "true") == 0) { - return_suppressed = true; + const char *ret_s + = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "return_suppressed"); + if (ret_s != NULL && strcmp (ret_s, "true") == 0) + { + return_suppressed = true; + } } + ja = json_array (); + GNUNET_break (NULL != ja); qs = TAH_plugin->get_reserve_balance_insufficient_inconsistency ( TAH_plugin->cls, limit, @@ -119,7 +117,6 @@ TAH_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_handler_get ( return_suppressed, &process_reserve_balance_insufficient_inconsistency, ja); - if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); @@ -134,6 +131,6 @@ TAH_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_handler_get ( return TALER_MHD_REPLY_JSON_PACK ( connection, MHD_HTTP_OK, - GNUNET_JSON_pack_array_steal ("reserve-balance-insufficient-inconsistency", + GNUNET_JSON_pack_array_steal ("reserve_balance_insufficient_inconsistency", ja)); } diff --git a/src/auditor/taler-auditor-httpd_reserve-balance-insufficient-inconsistency-upd.c b/src/auditor/taler-auditor-httpd_reserve-balance-insufficient-inconsistency-upd.c deleted file mode 100644 index d72915b06..000000000 --- a/src/auditor/taler-auditor-httpd_reserve-balance-insufficient-inconsistency-upd.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - 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 "platform.h" -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_json_lib.h> -#include <jansson.h> -#include <microhttpd.h> -#include <pthread.h> -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler-auditor-httpd.h" -#include "taler-auditor-httpd_reserve-balance-insufficient-inconsistency-upd.h" - -MHD_RESULT -TAH_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - enum GNUNET_DB_QueryStatus qs; - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no row id specified"); - - - struct TALER_AUDITORDB_Generic_Update gu; - - gu.row_id = row_id; - - struct GNUNET_JSON_Specification spec[] = { - - // GNUNET_JSON_spec_uint64 ("row_id", &gu.row_id), - GNUNET_JSON_spec_bool ("suppressed", &gu.suppressed), - - GNUNET_JSON_spec_end () - }; - - json_t *json; - - (void) rh; - (void) connection_cls; - (void) upload_data; - (void) upload_data_size; - { - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_post_json (connection, - connection_cls, - upload_data, - upload_data_size, - &json); - if (GNUNET_SYSERR == res) - return MHD_NO; - if ((GNUNET_NO == res) || - (NULL == json)) - return MHD_YES; - res = TALER_MHD_parse_json_data (connection, - json, - spec); - if (GNUNET_SYSERR == res) - { - json_decref (json); - return MHD_NO; /* hard failure */ - } - if (GNUNET_NO == res) - { - json_decref (json); - return MHD_YES; /* failure */ - } - } - - /* execute transaction */ - qs = TAH_plugin->update_reserve_balance_insufficient_inconsistency ( - TAH_plugin->cls, &gu); - - GNUNET_JSON_parse_free (spec); - json_decref (json); - - MHD_RESULT ret = MHD_NO; - - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "update_account"); - break; - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "unexpected serialization problem"); - break; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no updates executed"); - break; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - ret = TALER_MHD_reply_static (connection, - MHD_HTTP_NO_CONTENT, - NULL, - NULL, - 0); - break; - } - - return ret; -} diff --git a/src/auditor/taler-auditor-httpd_reserve-balance-insufficient-inconsistency-upd.h b/src/auditor/taler-auditor-httpd_reserve-balance-insufficient-inconsistency-upd.h deleted file mode 100644 index 2b0df97dc..000000000 --- a/src/auditor/taler-auditor-httpd_reserve-balance-insufficient-inconsistency-upd.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_UPD_H -#define SRC_TALER_AUDITOR_HTTPD_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_UPD_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -MHD_RESULT -TAH_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_handler_update (struct - TAH_RequestHandler - *rh, - struct - MHD_Connection * - connection, - void ** - connection_cls, - const char * - upload_data, - size_t * - upload_data_size, - const char *const - args[]); - -#endif \ - // SRC_TALER_AUDITOR_HTTPD_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_UPD_H diff --git a/src/auditor/taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-del.c b/src/auditor/taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-del.c deleted file mode 100644 index 2a1eda133..000000000 --- a/src/auditor/taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-del.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - 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-auditor-httpd_reserve-balance-summary-wrong-inconsistency-del.h" - - -MHD_RESULT -TAH_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_handler_delete (struct - TAH_RequestHandler - *rh, - struct - MHD_Connection * - connection, - void ** - connection_cls, - const char * - upload_data, - size_t * - upload_data_size, - const char * - const args[]) -{ - - enum GNUNET_DB_QueryStatus qs; - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - - // execute the transaction - qs = TAH_plugin->delete_reserve_balance_summary_wrong_inconsistency ( - TAH_plugin->cls, - row_id); - - if (0 == qs) - { - // goes in here if there was an error with the transaction - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - TALER_LOG_WARNING ( - "Failed to handle DELETE /reserve-balance-summary-wrong-inconsistency/ %s", - args[1]); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - } - - // on success? - return TALER_MHD_REPLY_JSON_PACK (connection, - MHD_HTTP_NO_CONTENT, - GNUNET_JSON_pack_string ("status", - "RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_OK")); - -} diff --git a/src/auditor/taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-del.h b/src/auditor/taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-del.h deleted file mode 100644 index f269b52f5..000000000 --- a/src/auditor/taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-del.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - 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 TALER_AUDITOR_HTTPD_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_DEL_H -#define TALER_AUDITOR_HTTPD_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_DEL_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -/** - * Initialize subsystem. - */ -void -TEAH_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_DELETE_init (void); - -/** - * Shut down subsystem. - */ -void -TEAH_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_DELETE_done (void); - -/** - * Handle a "/reserve-balance-summary-wrong-inconsistency" request. Parses the JSON, and, if - * successful, checks the signatures and stores the result in the DB. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @param args NULL-terminated array of remaining parts of the URI broken up at '/' - * @return MHD result code - */ -MHD_RESULT -TAH_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_handler_delete ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - - -#endif diff --git a/src/auditor/taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-get.c b/src/auditor/taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-get.c index 39d13b2d6..689e0e0e4 100644 --- a/src/auditor/taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-get.c +++ b/src/auditor/taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-get.c @@ -13,8 +13,6 @@ You should have 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 "platform.h" #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_json_lib.h> @@ -26,38 +24,32 @@ #include "taler-auditor-httpd.h" #include "taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-get.h" + /** -* Add reserve-balance-summary-wrong-inconsistency to the list. -* -* @param[in,out] cls a `json_t *` array to extend -* @param serial_id location of the @a dc in the database -* @param dc struct of inconsistencies -* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating -*/ + * Add reserve-balance-summary-wrong-inconsistency to the list. + * + * @param[in,out] cls a `json_t *` array to extend + * @param dc struct of inconsistencies + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ static enum GNUNET_GenericReturnValue process_reserve_balance_summary_wrong_inconsistency ( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_ReserveBalanceSummaryWrongInconsistency *dc) { json_t *list = cls; json_t *obj; obj = GNUNET_JSON_PACK ( - - GNUNET_JSON_pack_int64 ("row_id", serial_id), + GNUNET_JSON_pack_int64 ("row_id", dc->row_id), GNUNET_JSON_pack_data_auto ("reserve_pub", &dc->reserve_pub), TALER_JSON_pack_amount ("exchange_amount", &dc->exchange_amount), TALER_JSON_pack_amount ("auditor_amount", &dc->auditor_amount), GNUNET_JSON_pack_bool ("suppressed", dc->suppressed) - - ); GNUNET_break (0 == json_array_append_new (list, obj)); - - return GNUNET_OK; } @@ -73,6 +65,9 @@ TAH_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_handler_get ( { json_t *ja; enum GNUNET_DB_QueryStatus qs; + int64_t limit = -20; + uint64_t offset; + bool return_suppressed = false; (void) rh; (void) connection_cls; @@ -87,35 +82,28 @@ TAH_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_handler_get ( TALER_EC_GENERIC_DB_SETUP_FAILED, NULL); } - ja = json_array (); - GNUNET_break (NULL != ja); - - int64_t limit = -20; - uint64_t offset; - TALER_MHD_parse_request_snumber (connection, "limit", &limit); - if (limit < 0) offset = INT64_MAX; else offset = 0; - TALER_MHD_parse_request_number (connection, "offset", &offset); - - bool return_suppressed = false; - const char *ret_s = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "return_suppressed"); - - if (ret_s != NULL && strcmp (ret_s, "true") == 0) { - return_suppressed = true; + const char *ret_s = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "return_suppressed"); + + if (ret_s != NULL && strcmp (ret_s, "true") == 0) + { + return_suppressed = true; + } } - + ja = json_array (); + GNUNET_break (NULL != ja); qs = TAH_plugin->get_reserve_balance_summary_wrong_inconsistency ( TAH_plugin->cls, limit, @@ -130,10 +118,11 @@ TAH_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_handler_get ( json_decref (ja); TALER_LOG_WARNING ( "Failed to handle GET /reserve-balance-summary-wrong-inconsistency"); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_FETCH_FAILED, - "reserve-balance-summary-wrong-inconsistency"); + return TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_FETCH_FAILED, + "reserve-balance-summary-wrong-inconsistency"); } return TALER_MHD_REPLY_JSON_PACK ( connection, diff --git a/src/auditor/taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-upd.c b/src/auditor/taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-upd.c deleted file mode 100644 index aa20c9ca7..000000000 --- a/src/auditor/taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-upd.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - 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 "platform.h" -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_json_lib.h> -#include <jansson.h> -#include <microhttpd.h> -#include <pthread.h> -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler-auditor-httpd.h" -#include "taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-upd.h" - -MHD_RESULT -TAH_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - enum GNUNET_DB_QueryStatus qs; - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no row id specified"); - - - struct TALER_AUDITORDB_Generic_Update gu; - - gu.row_id = row_id; - - struct GNUNET_JSON_Specification spec[] = { - - // GNUNET_JSON_spec_uint64 ("row_id", &gu.row_id), - GNUNET_JSON_spec_bool ("suppressed", &gu.suppressed), - - GNUNET_JSON_spec_end () - }; - - json_t *json; - - (void) rh; - (void) connection_cls; - (void) upload_data; - (void) upload_data_size; - { - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_post_json (connection, - connection_cls, - upload_data, - upload_data_size, - &json); - if (GNUNET_SYSERR == res) - return MHD_NO; - if ((GNUNET_NO == res) || - (NULL == json)) - return MHD_YES; - res = TALER_MHD_parse_json_data (connection, - json, - spec); - if (GNUNET_SYSERR == res) - { - json_decref (json); - return MHD_NO; /* hard failure */ - } - if (GNUNET_NO == res) - { - json_decref (json); - return MHD_YES; /* failure */ - } - } - - /* execute transaction */ - qs = TAH_plugin->update_reserve_balance_summary_wrong_inconsistency ( - TAH_plugin->cls, &gu); - - GNUNET_JSON_parse_free (spec); - json_decref (json); - - MHD_RESULT ret = MHD_NO; - - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "update_account"); - break; - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "unexpected serialization problem"); - break; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no updates executed"); - break; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - ret = TALER_MHD_reply_static (connection, - MHD_HTTP_NO_CONTENT, - NULL, - NULL, - 0); - break; - } - - return ret; -} diff --git a/src/auditor/taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-upd.h b/src/auditor/taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-upd.h deleted file mode 100644 index 939b4e01a..000000000 --- a/src/auditor/taler-auditor-httpd_reserve-balance-summary-wrong-inconsistency-upd.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - 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 \ - SRC_TALER_AUDITOR_HTTPD_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_UPD_H -#define \ - SRC_TALER_AUDITOR_HTTPD_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_UPD_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -MHD_RESULT -TAH_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_handler_update (struct - TAH_RequestHandler - *rh, - struct - MHD_Connection * - connection, - void ** - connection_cls, - const char * - upload_data, - size_t * - upload_data_size, - const char * - const args[]); - -#endif \ - // SRC_TALER_AUDITOR_HTTPD_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_UPD_H diff --git a/src/auditor/taler-auditor-httpd_reserve-in-inconsistency-del.c b/src/auditor/taler-auditor-httpd_reserve-in-inconsistency-del.c deleted file mode 100644 index 4096c3d0a..000000000 --- a/src/auditor/taler-auditor-httpd_reserve-in-inconsistency-del.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - 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-auditor-httpd_reserve-in-inconsistency-del.h" - - -MHD_RESULT -TAH_RESERVE_IN_INCONSISTENCY_handler_delete (struct TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - - enum GNUNET_DB_QueryStatus qs; - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - - // execute the transaction - qs = TAH_plugin->delete_reserve_in_inconsistency (TAH_plugin->cls, - row_id); - - if (0 == qs) - { - // goes in here if there was an error with the transaction - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - TALER_LOG_WARNING ( - "Failed to handle DELETE /reserve-in-inconsistency/ %s", - args[1]); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - } - - // on success? - return TALER_MHD_REPLY_JSON_PACK (connection, - MHD_HTTP_NO_CONTENT, - GNUNET_JSON_pack_string ("status", - "RESERVE_IN_INCONSISTENCY_OK")); - -} diff --git a/src/auditor/taler-auditor-httpd_reserve-in-inconsistency-del.h b/src/auditor/taler-auditor-httpd_reserve-in-inconsistency-del.h deleted file mode 100644 index 12cc7f63d..000000000 --- a/src/auditor/taler-auditor-httpd_reserve-in-inconsistency-del.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_RESERVE_IN_INCONSISTENCY_DEL_H -#define SRC_TALER_AUDITOR_HTTPD_RESERVE_IN_INCONSISTENCY_DEL_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -/** - * Initialize subsystem. - */ -void -TEAH_RESERVE_IN_INCONSISTENCY_DELETE_init (void); - -/** - * Shut down subsystem. - */ -void -TEAH_RESERVE_IN_INCONSISTENCY_DELETE_done (void); - -/** - * Handle a "/reserve-in-inconsistency" request. Parses the JSON, and, if - * successful, checks the signatures and stores the result in the DB. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @param args NULL-terminated array of remaining parts of the URI broken up at '/' - * @return MHD result code - */ -MHD_RESULT -TAH_RESERVE_IN_INCONSISTENCY_handler_delete ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - - -#endif diff --git a/src/auditor/taler-auditor-httpd_reserve-in-inconsistency-get.c b/src/auditor/taler-auditor-httpd_reserve-in-inconsistency-get.c index 514422e5d..0ec7b82ba 100644 --- a/src/auditor/taler-auditor-httpd_reserve-in-inconsistency-get.c +++ b/src/auditor/taler-auditor-httpd_reserve-in-inconsistency-get.c @@ -13,8 +13,6 @@ You should have 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 "platform.h" #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_json_lib.h> @@ -26,14 +24,15 @@ #include "taler-auditor-httpd.h" #include "taler-auditor-httpd_reserve-in-inconsistency-get.h" + /** -* Add reserve-in-inconsistency to the list. -* -* @param[in,out] cls a `json_t *` array to extend -* @param serial_id location of the @a dc in the database -* @param dc struct of inconsistencies -* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating -*/ + * Add reserve-in-inconsistency to the list. + * + * @param[in,out] cls a `json_t *` array to extend + * @param serial_id location of the @a dc in the database + * @param dc struct of inconsistencies + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ static enum GNUNET_GenericReturnValue process_reserve_in_inconsistency ( void *cls, @@ -44,18 +43,24 @@ process_reserve_in_inconsistency ( json_t *obj; obj = GNUNET_JSON_PACK ( - - GNUNET_JSON_pack_int64 ("row_id", serial_id), + GNUNET_JSON_pack_uint64 ("row_id", + serial_id), + GNUNET_JSON_pack_uint64 ("bank_row_id", + dc->bank_row_id), TALER_JSON_pack_amount ("amount_exchange_expected", &dc->amount_exchange_expected), - TALER_JSON_pack_amount ("amount_wired", &dc->amount_wired), - GNUNET_JSON_pack_data_auto ("reserve_pub", &dc->reserve_pub), - TALER_JSON_pack_time_abs_human ("timestamp", dc->timestamp), - GNUNET_JSON_pack_string ("account", dc->account), - GNUNET_JSON_pack_string ("diagnostic", dc->diagnostic), - GNUNET_JSON_pack_bool ("suppressed", dc->suppressed) - - + TALER_JSON_pack_amount ("amount_wired", + &dc->amount_wired), + GNUNET_JSON_pack_data_auto ("reserve_pub", + &dc->reserve_pub), + TALER_JSON_pack_time_abs_human ("timestamp", + dc->timestamp), + GNUNET_JSON_pack_string ("account", + dc->account), + GNUNET_JSON_pack_string ("diagnostic", + dc->diagnostic), + GNUNET_JSON_pack_bool ("suppressed", + dc->suppressed) ); GNUNET_break (0 == json_array_append_new (list, @@ -77,6 +82,9 @@ TAH_RESERVE_IN_INCONSISTENCY_handler_get ( { json_t *ja; enum GNUNET_DB_QueryStatus qs; + int64_t limit = -20; + uint64_t offset; + bool return_suppressed = false; (void) rh; (void) connection_cls; @@ -91,34 +99,30 @@ TAH_RESERVE_IN_INCONSISTENCY_handler_get ( TALER_EC_GENERIC_DB_SETUP_FAILED, NULL); } - ja = json_array (); - GNUNET_break (NULL != ja); - - int64_t limit = -20; - uint64_t offset; - TALER_MHD_parse_request_snumber (connection, "limit", &limit); - if (limit < 0) offset = INT64_MAX; else offset = 0; - TALER_MHD_parse_request_number (connection, "offset", &offset); - - bool return_suppressed = false; - const char *ret_s = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "return_suppressed"); - if (ret_s != NULL && strcmp (ret_s, "true") == 0) { - return_suppressed = true; + const char *ret_s + = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "return_suppressed"); + if ( (NULL != ret_s) && + (0 == strcmp (ret_s, + "true")) ) + { + return_suppressed = true; + } } - + ja = json_array (); + GNUNET_break (NULL != ja); qs = TAH_plugin->get_reserve_in_inconsistency ( TAH_plugin->cls, limit, @@ -126,13 +130,10 @@ TAH_RESERVE_IN_INCONSISTENCY_handler_get ( return_suppressed, &process_reserve_in_inconsistency, ja); - if (0 > qs) { - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); + GNUNET_break (0); json_decref (ja); - TALER_LOG_WARNING ( - "Failed to handle GET /reserve-in-inconsistency"); return TALER_MHD_reply_with_error (connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_GENERIC_DB_FETCH_FAILED, @@ -141,6 +142,6 @@ TAH_RESERVE_IN_INCONSISTENCY_handler_get ( return TALER_MHD_REPLY_JSON_PACK ( connection, MHD_HTTP_OK, - GNUNET_JSON_pack_array_steal ("reserve-in-inconsistency", + GNUNET_JSON_pack_array_steal ("reserve_in_inconsistency", ja)); } diff --git a/src/auditor/taler-auditor-httpd_reserve-in-inconsistency-upd.c b/src/auditor/taler-auditor-httpd_reserve-in-inconsistency-upd.c deleted file mode 100644 index c4707bb15..000000000 --- a/src/auditor/taler-auditor-httpd_reserve-in-inconsistency-upd.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - 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 "platform.h" -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_json_lib.h> -#include <jansson.h> -#include <microhttpd.h> -#include <pthread.h> -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler-auditor-httpd.h" -#include "taler-auditor-httpd_reserve-in-inconsistency-upd.h" - -MHD_RESULT -TAH_RESERVE_IN_INCONSISTENCY_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - enum GNUNET_DB_QueryStatus qs; - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no row id specified"); - - - struct TALER_AUDITORDB_Generic_Update gu; - - gu.row_id = row_id; - - struct GNUNET_JSON_Specification spec[] = { - - // GNUNET_JSON_spec_uint64 ("row_id", &gu.row_id), - GNUNET_JSON_spec_bool ("suppressed", &gu.suppressed), - - GNUNET_JSON_spec_end () - }; - - json_t *json; - - (void) rh; - (void) connection_cls; - (void) upload_data; - (void) upload_data_size; - { - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_post_json (connection, - connection_cls, - upload_data, - upload_data_size, - &json); - if (GNUNET_SYSERR == res) - return MHD_NO; - if ((GNUNET_NO == res) || - (NULL == json)) - return MHD_YES; - res = TALER_MHD_parse_json_data (connection, - json, - spec); - if (GNUNET_SYSERR == res) - { - json_decref (json); - return MHD_NO; /* hard failure */ - } - if (GNUNET_NO == res) - { - json_decref (json); - return MHD_YES; /* failure */ - } - } - - /* execute transaction */ - qs = TAH_plugin->update_reserve_in_inconsistency (TAH_plugin->cls, &gu); - - GNUNET_JSON_parse_free (spec); - json_decref (json); - - MHD_RESULT ret = MHD_NO; - - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "update_account"); - break; - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "unexpected serialization problem"); - break; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no updates executed"); - break; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - ret = TALER_MHD_reply_static (connection, - MHD_HTTP_NO_CONTENT, - NULL, - NULL, - 0); - break; - } - - return ret; -} diff --git a/src/auditor/taler-auditor-httpd_reserve-in-inconsistency-upd.h b/src/auditor/taler-auditor-httpd_reserve-in-inconsistency-upd.h deleted file mode 100644 index 0f66574df..000000000 --- a/src/auditor/taler-auditor-httpd_reserve-in-inconsistency-upd.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_RESERVE_IN_INCONSISTENCY_UPD_H -#define SRC_TALER_AUDITOR_HTTPD_RESERVE_IN_INCONSISTENCY_UPD_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -MHD_RESULT -TAH_RESERVE_IN_INCONSISTENCY_handler_update (struct TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif // SRC_TALER_AUDITOR_HTTPD_RESERVE_IN_INCONSISTENCY_UPD_H diff --git a/src/auditor/taler-auditor-httpd_reserve-not-closed-inconsistency-del.c b/src/auditor/taler-auditor-httpd_reserve-not-closed-inconsistency-del.c deleted file mode 100644 index 9d9e45094..000000000 --- a/src/auditor/taler-auditor-httpd_reserve-not-closed-inconsistency-del.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - 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-auditor-httpd_reserve-not-closed-inconsistency-del.h" - - -MHD_RESULT -TAH_RESERVE_NOT_CLOSED_INCONSISTENCY_handler_delete (struct - TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - - - enum GNUNET_DB_QueryStatus qs; - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - - // execute the transaction - qs = TAH_plugin->delete_reserve_not_closed_inconsistency (TAH_plugin->cls, - row_id); - - if (0 == qs) - { - // goes in here if there was an error with the transaction - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - TALER_LOG_WARNING ( - "Failed to handle DELETE /reserve-not-closed-inconsistency/ %s", - args[1]); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - } - - // on success? - return TALER_MHD_REPLY_JSON_PACK (connection, - MHD_HTTP_NO_CONTENT, - GNUNET_JSON_pack_string ("status", - "RESERVE_NOT_CLOSED_INCONSISTENCY_OK")); - - -} diff --git a/src/auditor/taler-auditor-httpd_reserve-not-closed-inconsistency-del.h b/src/auditor/taler-auditor-httpd_reserve-not-closed-inconsistency-del.h deleted file mode 100644 index 4f12a813b..000000000 --- a/src/auditor/taler-auditor-httpd_reserve-not-closed-inconsistency-del.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_RESERVE_NOT_CLOSED_INCONSISTENCY_DEL_H -#define SRC_TALER_AUDITOR_HTTPD_RESERVE_NOT_CLOSED_INCONSISTENCY_DEL_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -/** - * Initialize subsystem. - */ -void -TEAH_RESERVE_NOT_CLOSED_INCONSISTENCY_DELETE_init (void); - -/** - * Shut down subsystem. - */ -void -TEAH_RESERVE_NOT_CLOSED_INCONSISTENCY_DELETE_done (void); - -/** - * Handle a "/reserve-not-closed-inconsistency" request. Parses the JSON, and, if - * successful, checks the signatures and stores the result in the DB. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @param args NULL-terminated array of remaining parts of the URI broken up at '/' - * @return MHD result code - */ -MHD_RESULT -TAH_RESERVE_NOT_CLOSED_INCONSISTENCY_handler_delete ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - - -#endif diff --git a/src/auditor/taler-auditor-httpd_reserve-not-closed-inconsistency-get.c b/src/auditor/taler-auditor-httpd_reserve-not-closed-inconsistency-get.c index 807e6dc55..e9f4bf63b 100644 --- a/src/auditor/taler-auditor-httpd_reserve-not-closed-inconsistency-get.c +++ b/src/auditor/taler-auditor-httpd_reserve-not-closed-inconsistency-get.c @@ -13,8 +13,6 @@ You should have 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 "platform.h" #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_json_lib.h> @@ -26,39 +24,39 @@ #include "taler-auditor-httpd.h" #include "taler-auditor-httpd_reserve-not-closed-inconsistency-get.h" + /** -* Add reserve-not-closed-inconsistency to the list. -* -* @param[in,out] cls a `json_t *` array to extend -* @param serial_id location of the @a dc in the database -* @param dc struct of inconsistencies -* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating -*/ + * Add reserve-not-closed-inconsistency to the list. + * + * @param[in,out] cls a `json_t *` array to extend + * @param dc struct of inconsistencies + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ static enum GNUNET_GenericReturnValue process_reserve_not_closed_inconsistency ( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_ReserveNotClosedInconsistency *dc) { json_t *list = cls; json_t *obj; obj = GNUNET_JSON_PACK ( - - GNUNET_JSON_pack_int64 ("row_id", serial_id), - GNUNET_JSON_pack_data_auto ("reserve_pub", &dc->reserve_pub), - TALER_JSON_pack_amount ("balance", &dc->balance), - TALER_JSON_pack_time_abs_human ("expiration_time", dc->expiration_time), - GNUNET_JSON_pack_data_auto ("diagnostic", &dc->diagnostic), - GNUNET_JSON_pack_bool ("suppressed", dc->suppressed) - - + GNUNET_JSON_pack_uint64 ("row_id", + dc->row_id), + GNUNET_JSON_pack_data_auto ("reserve_pub", + &dc->reserve_pub), + TALER_JSON_pack_amount ("balance", + &dc->balance), + TALER_JSON_pack_time_abs_human ("expiration_time", + dc->expiration_time), + GNUNET_JSON_pack_string ("diagnostic", + dc->diagnostic), + GNUNET_JSON_pack_bool ("suppressed", + dc->suppressed) ); GNUNET_break (0 == json_array_append_new (list, obj)); - - return GNUNET_OK; } @@ -74,6 +72,9 @@ TAH_RESERVE_NOT_CLOSED_INCONSISTENCY_handler_get ( { json_t *ja; enum GNUNET_DB_QueryStatus qs; + int64_t limit = -20; + uint64_t offset; + bool return_suppressed = false; (void) rh; (void) connection_cls; @@ -88,34 +89,31 @@ TAH_RESERVE_NOT_CLOSED_INCONSISTENCY_handler_get ( TALER_EC_GENERIC_DB_SETUP_FAILED, NULL); } - ja = json_array (); - GNUNET_break (NULL != ja); - - int64_t limit = -20; - uint64_t offset; - TALER_MHD_parse_request_snumber (connection, "limit", &limit); - if (limit < 0) offset = INT64_MAX; else offset = 0; - TALER_MHD_parse_request_number (connection, "offset", &offset); - - bool return_suppressed = false; - const char *ret_s = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "return_suppressed"); - if (ret_s != NULL && strcmp (ret_s, "true") == 0) { - return_suppressed = true; + const char *ret_s + = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "return_suppressed"); + if ( (NULL != ret_s) && + (0 == strcmp (ret_s, + "true")) ) + { + return_suppressed = true; + } } + ja = json_array (); + GNUNET_break (NULL != ja); qs = TAH_plugin->get_reserve_not_closed_inconsistency ( TAH_plugin->cls, limit, @@ -123,7 +121,6 @@ TAH_RESERVE_NOT_CLOSED_INCONSISTENCY_handler_get ( return_suppressed, &process_reserve_not_closed_inconsistency, ja); - if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); diff --git a/src/auditor/taler-auditor-httpd_reserve-not-closed-inconsistency-upd.c b/src/auditor/taler-auditor-httpd_reserve-not-closed-inconsistency-upd.c deleted file mode 100644 index 586b15cdc..000000000 --- a/src/auditor/taler-auditor-httpd_reserve-not-closed-inconsistency-upd.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - 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 "platform.h" -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_json_lib.h> -#include <jansson.h> -#include <microhttpd.h> -#include <pthread.h> -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler-auditor-httpd.h" -#include "taler-auditor-httpd_reserve-not-closed-inconsistency-upd.h" - -MHD_RESULT -TAH_RESERVE_NOT_CLOSED_INCONSISTENCY_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - enum GNUNET_DB_QueryStatus qs; - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no row id specified"); - - - struct TALER_AUDITORDB_Generic_Update gu; - - gu.row_id = row_id; - - struct GNUNET_JSON_Specification spec[] = { - - // GNUNET_JSON_spec_uint64 ("row_id", &gu.row_id), - GNUNET_JSON_spec_bool ("suppressed", &gu.suppressed), - - GNUNET_JSON_spec_end () - }; - - json_t *json; - - (void) rh; - (void) connection_cls; - (void) upload_data; - (void) upload_data_size; - { - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_post_json (connection, - connection_cls, - upload_data, - upload_data_size, - &json); - if (GNUNET_SYSERR == res) - return MHD_NO; - if ((GNUNET_NO == res) || - (NULL == json)) - return MHD_YES; - res = TALER_MHD_parse_json_data (connection, - json, - spec); - if (GNUNET_SYSERR == res) - { - json_decref (json); - return MHD_NO; /* hard failure */ - } - if (GNUNET_NO == res) - { - json_decref (json); - return MHD_YES; /* failure */ - } - } - - /* execute transaction */ - qs = TAH_plugin->update_reserve_not_closed_inconsistency (TAH_plugin->cls, - &gu); - - GNUNET_JSON_parse_free (spec); - json_decref (json); - - MHD_RESULT ret = MHD_NO; - - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "update_account"); - break; - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "unexpected serialization problem"); - break; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no updates executed"); - break; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - ret = TALER_MHD_reply_static (connection, - MHD_HTTP_NO_CONTENT, - NULL, - NULL, - 0); - break; - } - - return ret; -} diff --git a/src/auditor/taler-auditor-httpd_reserve-not-closed-inconsistency-upd.h b/src/auditor/taler-auditor-httpd_reserve-not-closed-inconsistency-upd.h deleted file mode 100644 index 7a8fa6d4e..000000000 --- a/src/auditor/taler-auditor-httpd_reserve-not-closed-inconsistency-upd.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_RESERVE_NOT_CLOSED_INCONSISTENCY_UPD_H -#define SRC_TALER_AUDITOR_HTTPD_RESERVE_NOT_CLOSED_INCONSISTENCY_UPD_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -MHD_RESULT -TAH_RESERVE_NOT_CLOSED_INCONSISTENCY_handler_update (struct - TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif // SRC_TALER_AUDITOR_HTTPD_RESERVE_NOT_CLOSED_INCONSISTENCY_UPD_H diff --git a/src/auditor/taler-auditor-httpd_reserves-get.c b/src/auditor/taler-auditor-httpd_reserves-get.c index 6f6a3be2c..901557475 100644 --- a/src/auditor/taler-auditor-httpd_reserves-get.c +++ b/src/auditor/taler-auditor-httpd_reserves-get.c @@ -13,8 +13,6 @@ You should have 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 "platform.h" #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_json_lib.h> @@ -26,14 +24,15 @@ #include "taler-auditor-httpd.h" #include "taler-auditor-httpd_reserves-get.h" + /** -* Add reserves to the list. -* -* @param[in,out] cls a `json_t *` array to extend -* @param serial_id location of the @a dc in the database -* @param dc struct of inconsistencies -* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating -*/ + * Add reserves to the list. + * + * @param[in,out] cls a `json_t *` array to extend + * @param serial_id location of the @a dc in the database + * @param dc struct of inconsistencies + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ static enum GNUNET_GenericReturnValue process_reserves ( void *cls, @@ -44,7 +43,6 @@ process_reserves ( json_t *obj; obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_int64 ("auditor_reserves_rowid", dc->auditor_reserves_rowid), GNUNET_JSON_pack_data_auto ("reserve_pub", &dc->reserve_pub), @@ -57,14 +55,10 @@ process_reserves ( TALER_JSON_pack_amount ("history_fee_balance", &dc->history_fee_balance), TALER_JSON_pack_time_abs_human ("expiration_date", dc->expiration_date), GNUNET_JSON_pack_string ("origin_account", dc->origin_account) - - ); GNUNET_break (0 == json_array_append_new (list, obj)); - - return GNUNET_OK; } @@ -80,6 +74,8 @@ TAH_RESERVES_handler_get ( { json_t *ja; enum GNUNET_DB_QueryStatus qs; + int64_t limit = -20; + uint64_t offset; (void) rh; (void) connection_cls; @@ -94,12 +90,6 @@ TAH_RESERVES_handler_get ( TALER_EC_GENERIC_DB_SETUP_FAILED, NULL); } - ja = json_array (); - GNUNET_break (NULL != ja); - - int64_t limit = -20; - uint64_t offset; - TALER_MHD_parse_request_snumber (connection, "limit", &limit); @@ -108,21 +98,17 @@ TAH_RESERVES_handler_get ( offset = INT64_MAX; else offset = 0; - TALER_MHD_parse_request_number (connection, "offset", &offset); - - bool return_suppressed = false; - + ja = json_array (); + GNUNET_break (NULL != ja); qs = TAH_plugin->get_reserves ( TAH_plugin->cls, limit, offset, - return_suppressed, &process_reserves, ja); - if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); diff --git a/src/auditor/taler-auditor-httpd_row-inconsistency-del.c b/src/auditor/taler-auditor-httpd_row-inconsistency-del.c deleted file mode 100644 index 98f848161..000000000 --- a/src/auditor/taler-auditor-httpd_row-inconsistency-del.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - 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-auditor-httpd_row-inconsistency-del.h" - - -MHD_RESULT -TAH_ROW_INCONSISTENCY_handler_delete (struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - - enum GNUNET_DB_QueryStatus qs; - - uint64_t row_id = atoi (args[1]); - - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - - // execute the transaction - qs = TAH_plugin->delete_row_inconsistency (TAH_plugin->cls,row_id); - - if (0 > qs) - { - // goes in here if there was an error with the transaction - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - TALER_LOG_WARNING ("Failed to handle DELETE /row-inconsistency/ %s\n", - args[1]); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - } - - // on success? - return TALER_MHD_REPLY_JSON_PACK (connection, - MHD_HTTP_NO_CONTENT, - GNUNET_JSON_pack_string ("status", - "ROW_INCONSISTENCY_OK")); - -}
\ No newline at end of file diff --git a/src/auditor/taler-auditor-httpd_row-inconsistency-del.h b/src/auditor/taler-auditor-httpd_row-inconsistency-del.h deleted file mode 100644 index 6611d9812..000000000 --- a/src/auditor/taler-auditor-httpd_row-inconsistency-del.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_ROW_INCONSISTENCY_DEL_H -#define SRC_TALER_AUDITOR_HTTPD_ROW_INCONSISTENCY_DEL_H - - -#include <gnunet/gnunet_util_lib.h> -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -/** - * Initialize subsystem. - */ -void -TEAH_ROW_INCONSISTENCY_DELETE_init (void); - -/** - * Shut down subsystem. - */ -void -TEAH_ROW_INCONSISTENCY_DELETE_done (void); - -/** - * Handle a "/deposit-confirmation" request. Parses the JSON, and, if - * successful, checks the signatures and stores the result in the DB. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @param args NULL-terminated array of remaining parts of the URI broken up at '/' - * @return MHD result code - */ -MHD_RESULT -TAH_ROW_INCONSISTENCY_handler_delete ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - - -#endif diff --git a/src/auditor/taler-auditor-httpd_row-inconsistency-get.c b/src/auditor/taler-auditor-httpd_row-inconsistency-get.c index f1120b674..05bd21280 100644 --- a/src/auditor/taler-auditor-httpd_row-inconsistency-get.c +++ b/src/auditor/taler-auditor-httpd_row-inconsistency-get.c @@ -13,8 +13,6 @@ You should have 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 "platform.h" #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_json_lib.h> @@ -24,9 +22,9 @@ #include "taler_json_lib.h" #include "taler_mhd_lib.h" #include "taler-auditor-httpd.h" - #include "taler-auditor-httpd_row-inconsistency-get.h" + /** * Add deposit confirmation to the list. * @@ -57,7 +55,6 @@ add_row_inconsistency ( GNUNET_break (0 == json_array_append_new (list, obj)); - return GNUNET_OK; } @@ -73,6 +70,9 @@ TAH_ROW_INCONSISTENCY_handler_get ( { json_t *ja; enum GNUNET_DB_QueryStatus qs; + int64_t limit = -20; + uint64_t offset; + bool return_suppressed = false; (void) rh; (void) connection_cls; @@ -87,34 +87,28 @@ TAH_ROW_INCONSISTENCY_handler_get ( TALER_EC_GENERIC_DB_SETUP_FAILED, NULL); } - ja = json_array (); - GNUNET_break (NULL != ja); - - int64_t limit = -20; - uint64_t offset; - TALER_MHD_parse_request_snumber (connection, "limit", &limit); - if (limit < 0) offset = INT64_MAX; else offset = 0; - TALER_MHD_parse_request_number (connection, "offset", &offset); - - bool return_suppressed = false; - const char *ret_s = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "return_suppressed"); - if (ret_s != NULL && strcmp (ret_s, "true") == 0) { - return_suppressed = true; + const char *ret_s = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "return_suppressed"); + if (ret_s != NULL && strcmp (ret_s, "true") == 0) + { + return_suppressed = true; + } } + ja = json_array (); + GNUNET_break (NULL != ja); qs = TAH_plugin->get_row_inconsistency ( TAH_plugin->cls, limit, @@ -122,7 +116,6 @@ TAH_ROW_INCONSISTENCY_handler_get ( return_suppressed, &add_row_inconsistency, ja); - if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); diff --git a/src/auditor/taler-auditor-httpd_row-inconsistency-upd.c b/src/auditor/taler-auditor-httpd_row-inconsistency-upd.c deleted file mode 100644 index 405af1414..000000000 --- a/src/auditor/taler-auditor-httpd_row-inconsistency-upd.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - 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 "platform.h" -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_json_lib.h> -#include <jansson.h> -#include <microhttpd.h> -#include <pthread.h> -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler-auditor-httpd.h" -#include "taler-auditor-httpd_row-inconsistency-upd.h" - -MHD_RESULT -TAH_ROW_INCONSISTENCY_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - enum GNUNET_DB_QueryStatus qs; - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no row id specified"); - - - struct TALER_AUDITORDB_Generic_Update gu; - - gu.row_id = row_id; - - struct GNUNET_JSON_Specification spec[] = { - - // GNUNET_JSON_spec_uint64 ("row_id", &gu.row_id), - GNUNET_JSON_spec_bool ("suppressed", &gu.suppressed), - - GNUNET_JSON_spec_end () - }; - - json_t *json; - - (void) rh; - (void) connection_cls; - (void) upload_data; - (void) upload_data_size; - { - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_post_json (connection, - connection_cls, - upload_data, - upload_data_size, - &json); - if (GNUNET_SYSERR == res) - return MHD_NO; - if ((GNUNET_NO == res) || - (NULL == json)) - return MHD_YES; - res = TALER_MHD_parse_json_data (connection, - json, - spec); - if (GNUNET_SYSERR == res) - { - json_decref (json); - return MHD_NO; /* hard failure */ - } - if (GNUNET_NO == res) - { - json_decref (json); - return MHD_YES; /* failure */ - } - } - - /* execute transaction */ - qs = TAH_plugin->update_row_inconsistency (TAH_plugin->cls, &gu); - - GNUNET_JSON_parse_free (spec); - json_decref (json); - - MHD_RESULT ret = MHD_NO; - - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "update_account"); - break; - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "unexpected serialization problem"); - break; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no updates executed"); - break; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - ret = TALER_MHD_reply_static (connection, - MHD_HTTP_NO_CONTENT, - NULL, - NULL, - 0); - break; - } - - return ret; -} diff --git a/src/auditor/taler-auditor-httpd_row-inconsistency-upd.h b/src/auditor/taler-auditor-httpd_row-inconsistency-upd.h deleted file mode 100644 index 9b29d1e0d..000000000 --- a/src/auditor/taler-auditor-httpd_row-inconsistency-upd.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_ROW_INCONSISTENCY_UPD_H -#define SRC_TALER_AUDITOR_HTTPD_ROW_INCONSISTENCY_UPD_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -MHD_RESULT -TAH_ROW_INCONSISTENCY_handler_update (struct TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif // SRC_TALER_AUDITOR_HTTPD_ROW_INCONSISTENCY_UPD_H diff --git a/src/auditor/taler-auditor-httpd_row-minor-inconsistencies-del.c b/src/auditor/taler-auditor-httpd_row-minor-inconsistencies-del.c deleted file mode 100644 index 3748a627f..000000000 --- a/src/auditor/taler-auditor-httpd_row-minor-inconsistencies-del.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - 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-auditor-httpd_row-minor-inconsistencies-del.h" - - -MHD_RESULT -TAH_ROW_MINOR_INCONSISTENCIES_handler_delete (struct TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - - enum GNUNET_DB_QueryStatus qs; - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - - // execute the transaction - qs = TAH_plugin->delete_row_minor_inconsistencies (TAH_plugin->cls, - row_id); - - if (0 == qs) - { - // goes in here if there was an error with the transaction - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - TALER_LOG_WARNING ( - "Failed to handle DELETE /row-minor-inconsistencies/ %s", - args[1]); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - } - - // on success? - return TALER_MHD_REPLY_JSON_PACK (connection, - MHD_HTTP_NO_CONTENT, - GNUNET_JSON_pack_string ("status", - "ROW_MINOR_INCONSISTENCIES_OK")); - -} diff --git a/src/auditor/taler-auditor-httpd_row-minor-inconsistencies-del.h b/src/auditor/taler-auditor-httpd_row-minor-inconsistencies-del.h deleted file mode 100644 index 802607201..000000000 --- a/src/auditor/taler-auditor-httpd_row-minor-inconsistencies-del.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_ROW_MINOR_INCONSISTENCIES_DEL_H -#define SRC_TALER_AUDITOR_HTTPD_ROW_MINOR_INCONSISTENCIES_DEL_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -/** - * Initialize subsystem. - */ -void -TEAH_ROW_MINOR_INCONSISTENCIES_DELETE_init (void); - -/** - * Shut down subsystem. - */ -void -TEAH_ROW_MINOR_INCONSISTENCIES_DELETE_done (void); - -/** - * Handle a "/row-minor-inconsistencies" request. Parses the JSON, and, if - * successful, checks the signatures and stores the result in the DB. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @param args NULL-terminated array of remaining parts of the URI broken up at '/' - * @return MHD result code - */ -MHD_RESULT -TAH_ROW_MINOR_INCONSISTENCIES_handler_delete ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - - -#endif diff --git a/src/auditor/taler-auditor-httpd_row-minor-inconsistencies-get.c b/src/auditor/taler-auditor-httpd_row-minor-inconsistencies-get.c index 7585bb9cd..44f2c0844 100644 --- a/src/auditor/taler-auditor-httpd_row-minor-inconsistencies-get.c +++ b/src/auditor/taler-auditor-httpd_row-minor-inconsistencies-get.c @@ -13,8 +13,6 @@ You should have 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 "platform.h" #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_json_lib.h> @@ -26,37 +24,37 @@ #include "taler-auditor-httpd.h" #include "taler-auditor-httpd_row-minor-inconsistencies-get.h" + /** -* Add row-minor-inconsistencies to the list. -* -* @param[in,out] cls a `json_t *` array to extend -* @param serial_id location of the @a dc in the database -* @param dc struct of inconsistencies -* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + * Add row-minor-inconsistencies to the list. + * + * @param[in,out] cls a `json_t *` array to extend + * @param dc struct of inconsistencies + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating */ static enum GNUNET_GenericReturnValue process_row_minor_inconsistencies ( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_RowMinorInconsistencies *dc) { json_t *list = cls; json_t *obj; obj = GNUNET_JSON_PACK ( - - GNUNET_JSON_pack_int64 ("row_id", serial_id), - GNUNET_JSON_pack_string ("row_table", dc->row_table), - GNUNET_JSON_pack_string ("diagnostic", dc->diagnostic), - GNUNET_JSON_pack_bool ("suppressed", dc->suppressed) - - + GNUNET_JSON_pack_int64 ("row_id", + dc->row_id), + GNUNET_JSON_pack_string ("row_table", + dc->row_table), + GNUNET_JSON_pack_int64 ("problem_row", + dc->problem_row), + GNUNET_JSON_pack_string ("diagnostic", + dc->diagnostic), + GNUNET_JSON_pack_bool ("suppressed", + dc->suppressed) ); GNUNET_break (0 == json_array_append_new (list, obj)); - - return GNUNET_OK; } @@ -72,6 +70,9 @@ TAH_ROW_MINOR_INCONSISTENCIES_handler_get ( { json_t *ja; enum GNUNET_DB_QueryStatus qs; + int64_t limit = -20; + uint64_t offset; + bool return_suppressed = false; (void) rh; (void) connection_cls; @@ -86,34 +87,32 @@ TAH_ROW_MINOR_INCONSISTENCIES_handler_get ( TALER_EC_GENERIC_DB_SETUP_FAILED, NULL); } - ja = json_array (); - GNUNET_break (NULL != ja); - - int64_t limit = -20; - uint64_t offset; - TALER_MHD_parse_request_snumber (connection, "limit", &limit); - if (limit < 0) offset = INT64_MAX; else offset = 0; - TALER_MHD_parse_request_number (connection, "offset", &offset); - - bool return_suppressed = false; - const char *ret_s = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "return_suppressed"); - if (ret_s != NULL && strcmp (ret_s, "true") == 0) { - return_suppressed = true; + const char *ret_s + = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "return_suppressed"); + + if ( (NULL != ret_s) && + (0 == strcmp (ret_s, + "true")) ) + { + return_suppressed = true; + } } + ja = json_array (); + GNUNET_break (NULL != ja); qs = TAH_plugin->get_row_minor_inconsistencies ( TAH_plugin->cls, limit, @@ -136,6 +135,6 @@ TAH_ROW_MINOR_INCONSISTENCIES_handler_get ( return TALER_MHD_REPLY_JSON_PACK ( connection, MHD_HTTP_OK, - GNUNET_JSON_pack_array_steal ("row-minor-inconsistencies", + GNUNET_JSON_pack_array_steal ("row_minor_inconsistencies", ja)); } diff --git a/src/auditor/taler-auditor-httpd_row-minor-inconsistencies-upd.c b/src/auditor/taler-auditor-httpd_row-minor-inconsistencies-upd.c deleted file mode 100644 index 515b2ea10..000000000 --- a/src/auditor/taler-auditor-httpd_row-minor-inconsistencies-upd.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - 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 "platform.h" -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_json_lib.h> -#include <jansson.h> -#include <microhttpd.h> -#include <pthread.h> -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler-auditor-httpd.h" -#include "taler-auditor-httpd_row-minor-inconsistencies-upd.h" - -MHD_RESULT -TAH_ROW_MINOR_INCONSISTENCIES_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - enum GNUNET_DB_QueryStatus qs; - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no row id specified"); - - - struct TALER_AUDITORDB_Generic_Update gu; - - gu.row_id = row_id; - - struct GNUNET_JSON_Specification spec[] = { - - // GNUNET_JSON_spec_uint64 ("row_id", &gu.row_id), - GNUNET_JSON_spec_bool ("suppressed", &gu.suppressed), - - GNUNET_JSON_spec_end () - }; - - json_t *json; - - (void) rh; - (void) connection_cls; - (void) upload_data; - (void) upload_data_size; - { - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_post_json (connection, - connection_cls, - upload_data, - upload_data_size, - &json); - if (GNUNET_SYSERR == res) - return MHD_NO; - if ((GNUNET_NO == res) || - (NULL == json)) - return MHD_YES; - res = TALER_MHD_parse_json_data (connection, - json, - spec); - if (GNUNET_SYSERR == res) - { - json_decref (json); - return MHD_NO; /* hard failure */ - } - if (GNUNET_NO == res) - { - json_decref (json); - return MHD_YES; /* failure */ - } - } - - /* execute transaction */ - qs = TAH_plugin->update_row_minor_inconsistencies (TAH_plugin->cls, &gu); - - GNUNET_JSON_parse_free (spec); - json_decref (json); - - MHD_RESULT ret = MHD_NO; - - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "update_account"); - break; - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "unexpected serialization problem"); - break; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no updates executed"); - break; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - ret = TALER_MHD_reply_static (connection, - MHD_HTTP_NO_CONTENT, - NULL, - NULL, - 0); - break; - } - - return ret; -} diff --git a/src/auditor/taler-auditor-httpd_row-minor-inconsistencies-upd.h b/src/auditor/taler-auditor-httpd_row-minor-inconsistencies-upd.h deleted file mode 100644 index 8ff1fd16d..000000000 --- a/src/auditor/taler-auditor-httpd_row-minor-inconsistencies-upd.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_ROW_MINOR_INCONSISTENCIES_UPD_H -#define SRC_TALER_AUDITOR_HTTPD_ROW_MINOR_INCONSISTENCIES_UPD_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -MHD_RESULT -TAH_ROW_MINOR_INCONSISTENCIES_handler_update (struct TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif // SRC_TALER_AUDITOR_HTTPD_ROW_MINOR_INCONSISTENCIES_UPD_H diff --git a/src/auditor/taler-auditor-httpd_spa.c b/src/auditor/taler-auditor-httpd_spa.c new file mode 100644 index 000000000..ed9bc6c53 --- /dev/null +++ b/src/auditor/taler-auditor-httpd_spa.c @@ -0,0 +1,84 @@ +/* + This file is part of TALER + Copyright (C) 2020, 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 EXCHANGEABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> +*/ +/** + * @file taler-auditor-httpd_spa.c + * @brief logic to load single page app (/spa) + * @author Christian Grothoff + */ +#include "platform.h" +#include <gnunet/gnunet_util_lib.h> +#include "taler_util.h" +#include "taler_mhd_lib.h" +#include <gnunet/gnunet_mhd_compat.h> +#include "taler-auditor-httpd_spa.h" + + +/** + * Resources of the auditor SPA. + */ +static struct TALER_MHD_Spa *spa; + + +MHD_RESULT +TAH_spa_handler ( + /* const */ struct TAH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size, + const char *const args[]) +{ + const char *path = args[1]; + + GNUNET_assert (0 == strcmp (args[0], + "spa")); + if (NULL == path) + path = "index.html"; + return TALER_MHD_spa_handler (spa, + connection, + path); +} + + +enum GNUNET_GenericReturnValue +TAH_spa_init () +{ + spa = TALER_MHD_spa_load ("auditor/spa/"); + if (NULL == spa) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + +/** + * Nicely shut down. + */ +void __attribute__ ((destructor)) +get_spa_fini (void); + +/* declaration to suppress compiler warning */ +void __attribute__ ((destructor)) +get_spa_fini () +{ + if (NULL != spa) + { + TALER_MHD_spa_free (spa); + spa = NULL; + } +} diff --git a/src/auditor/taler-auditor-httpd_spa.h b/src/auditor/taler-auditor-httpd_spa.h new file mode 100644 index 000000000..f8a6c98f2 --- /dev/null +++ b/src/auditor/taler-auditor-httpd_spa.h @@ -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 EXCHANGEABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> +*/ +/** + * @file taler-auditor-httpd_spa.h + * @brief logic to preload and serve static files + * @author Christian Grothoff + */ +#ifndef TALER_AUDITOR_HTTPD_SPA_H +#define TALER_AUDITOR_HTTPD_SPA_H + +#include <microhttpd.h> +#include "taler-auditor-httpd.h" + + +/** + * Return our single-page-app user interface + * for staff (see contrib/wallet-core/). + * + * @param rh request context + * @param connection the MHD connection to handle + * @param[in,out] connection_cls the connection's closure (can be updated) + * @param upload_data upload data + * @param[in,out] upload_data_size number of bytes (left) in @a upload_data + * @param args request URL broken up into tokens at '/' characters + * @return MHD result code + */ +MHD_RESULT +TAH_spa_handler ( + /* const */ struct TAH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size, + const char *const args[]); + + +/** + * Preload and compress SPA files. + * + * @return #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +TAH_spa_init (void); + + +#endif diff --git a/src/auditor/taler-auditor-httpd_wire-format-inconsistency-del.c b/src/auditor/taler-auditor-httpd_wire-format-inconsistency-del.c deleted file mode 100644 index d26e860be..000000000 --- a/src/auditor/taler-auditor-httpd_wire-format-inconsistency-del.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - 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-auditor-httpd_wire-format-inconsistency-del.h" - - -MHD_RESULT -TAH_WIRE_FORMAT_INCONSISTENCY_handler_delete (struct TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - - enum GNUNET_DB_QueryStatus qs; - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - - // execute the transaction - qs = TAH_plugin->delete_wire_format_inconsistency (TAH_plugin->cls, - row_id); - - if (0 == qs) - { - // goes in here if there was an error with the transaction - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - TALER_LOG_WARNING ( - "Failed to handle DELETE /wire-format-inconsistency/ %s", - args[1]); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - } - - // on success? - return TALER_MHD_REPLY_JSON_PACK (connection, - MHD_HTTP_NO_CONTENT, - GNUNET_JSON_pack_string ("status", - "WIRE_FORMAT_INCONSISTENCY_OK")); - -} diff --git a/src/auditor/taler-auditor-httpd_wire-format-inconsistency-del.h b/src/auditor/taler-auditor-httpd_wire-format-inconsistency-del.h deleted file mode 100644 index 67bf64db1..000000000 --- a/src/auditor/taler-auditor-httpd_wire-format-inconsistency-del.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_WIRE_FORMAT_INCONSISTENCY_DEL_H -#define SRC_TALER_AUDITOR_HTTPD_WIRE_FORMAT_INCONSISTENCY_DEL_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -/** - * Initialize subsystem. - */ -void -TEAH_WIRE_FORMAT_INCONSISTENCY_DELETE_init (void); - -/** - * Shut down subsystem. - */ -void -TEAH_WIRE_FORMAT_INCONSISTENCY_DELETE_done (void); - -/** - * Handle a "/wire-format-inconsistency" request. Parses the JSON, and, if - * successful, checks the signatures and stores the result in the DB. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @param args NULL-terminated array of remaining parts of the URI broken up at '/' - * @return MHD result code - */ -MHD_RESULT -TAH_WIRE_FORMAT_INCONSISTENCY_handler_delete ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - - -#endif diff --git a/src/auditor/taler-auditor-httpd_wire-format-inconsistency-get.c b/src/auditor/taler-auditor-httpd_wire-format-inconsistency-get.c index 1c0b911a2..ce9986f6b 100644 --- a/src/auditor/taler-auditor-httpd_wire-format-inconsistency-get.c +++ b/src/auditor/taler-auditor-httpd_wire-format-inconsistency-get.c @@ -13,8 +13,6 @@ You should have 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 "platform.h" #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_json_lib.h> @@ -26,32 +24,33 @@ #include "taler-auditor-httpd.h" #include "taler-auditor-httpd_wire-format-inconsistency-get.h" + /** -* Add wire-format-inconsistency to the list. -* -* @param[in,out] cls a `json_t *` array to extend -* @param serial_id location of the @a dc in the database -* @param dc struct of inconsistencies -* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating -*/ + * Add wire-format-inconsistency to the list. + * + * @param[in,out] cls a `json_t *` array to extend + * @param dc struct of inconsistencies + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ static enum GNUNET_GenericReturnValue process_wire_format_inconsistency ( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_WireFormatInconsistency *dc) { json_t *list = cls; json_t *obj; obj = GNUNET_JSON_PACK ( - - GNUNET_JSON_pack_int64 ("row_id", serial_id), - TALER_JSON_pack_amount ("amount", &dc->amount), - GNUNET_JSON_pack_int64 ("wire_offset", dc->wire_offset), - GNUNET_JSON_pack_data_auto ("diagnostic", dc->diagnostic), - GNUNET_JSON_pack_bool ("suppressed", dc->suppressed) - - + GNUNET_JSON_pack_uint64 ("row_id", + dc->row_id), + TALER_JSON_pack_amount ("amount", + &dc->amount), + GNUNET_JSON_pack_uint64 ("wire_offset", + dc->wire_offset), + GNUNET_JSON_pack_string ("diagnostic", + dc->diagnostic), + GNUNET_JSON_pack_bool ("suppressed", + dc->suppressed) ); GNUNET_break (0 == json_array_append_new (list, @@ -73,6 +72,9 @@ TAH_WIRE_FORMAT_INCONSISTENCY_handler_get ( { json_t *ja; enum GNUNET_DB_QueryStatus qs; + int64_t limit = -20; + uint64_t offset; + bool return_suppressed = false; (void) rh; (void) connection_cls; @@ -87,34 +89,29 @@ TAH_WIRE_FORMAT_INCONSISTENCY_handler_get ( TALER_EC_GENERIC_DB_SETUP_FAILED, NULL); } - ja = json_array (); - GNUNET_break (NULL != ja); - - int64_t limit = -20; - uint64_t offset; - TALER_MHD_parse_request_snumber (connection, "limit", &limit); - if (limit < 0) offset = INT64_MAX; else offset = 0; - TALER_MHD_parse_request_number (connection, "offset", &offset); - - bool return_suppressed = false; - const char *ret_s = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "return_suppressed"); - if (ret_s != NULL && strcmp (ret_s, "true") == 0) { - return_suppressed = true; + const char *ret_s = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "return_suppressed"); + if ( (NULL != ret_s) && + (0 == strcmp (ret_s, "true")) ) + { + return_suppressed = true; + } } + ja = json_array (); + GNUNET_break (NULL != ja); qs = TAH_plugin->get_wire_format_inconsistency ( TAH_plugin->cls, limit, @@ -122,7 +119,6 @@ TAH_WIRE_FORMAT_INCONSISTENCY_handler_get ( return_suppressed, &process_wire_format_inconsistency, ja); - if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); @@ -137,6 +133,6 @@ TAH_WIRE_FORMAT_INCONSISTENCY_handler_get ( return TALER_MHD_REPLY_JSON_PACK ( connection, MHD_HTTP_OK, - GNUNET_JSON_pack_array_steal ("wire-format-inconsistency", + GNUNET_JSON_pack_array_steal ("wire_format_inconsistency", ja)); } diff --git a/src/auditor/taler-auditor-httpd_wire-format-inconsistency-upd.c b/src/auditor/taler-auditor-httpd_wire-format-inconsistency-upd.c deleted file mode 100644 index de3b90c2d..000000000 --- a/src/auditor/taler-auditor-httpd_wire-format-inconsistency-upd.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - 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 "platform.h" -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_json_lib.h> -#include <jansson.h> -#include <microhttpd.h> -#include <pthread.h> -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler-auditor-httpd.h" -#include "taler-auditor-httpd_wire-format-inconsistency-upd.h" - -MHD_RESULT -TAH_WIRE_FORMAT_INCONSISTENCY_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - enum GNUNET_DB_QueryStatus qs; - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no row id specified"); - - - struct TALER_AUDITORDB_Generic_Update gu; - - gu.row_id = row_id; - - struct GNUNET_JSON_Specification spec[] = { - - // GNUNET_JSON_spec_uint64 ("row_id", &gu.row_id), - GNUNET_JSON_spec_bool ("suppressed", &gu.suppressed), - - GNUNET_JSON_spec_end () - }; - - json_t *json; - - (void) rh; - (void) connection_cls; - (void) upload_data; - (void) upload_data_size; - { - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_post_json (connection, - connection_cls, - upload_data, - upload_data_size, - &json); - if (GNUNET_SYSERR == res) - return MHD_NO; - if ((GNUNET_NO == res) || - (NULL == json)) - return MHD_YES; - res = TALER_MHD_parse_json_data (connection, - json, - spec); - if (GNUNET_SYSERR == res) - { - json_decref (json); - return MHD_NO; /* hard failure */ - } - if (GNUNET_NO == res) - { - json_decref (json); - return MHD_YES; /* failure */ - } - } - - /* execute transaction */ - qs = TAH_plugin->update_wire_format_inconsistency (TAH_plugin->cls, &gu); - - GNUNET_JSON_parse_free (spec); - json_decref (json); - - MHD_RESULT ret = MHD_NO; - - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "update_account"); - break; - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "unexpected serialization problem"); - break; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no updates executed"); - break; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - ret = TALER_MHD_reply_static (connection, - MHD_HTTP_NO_CONTENT, - NULL, - NULL, - 0); - break; - } - - return ret; -} diff --git a/src/auditor/taler-auditor-httpd_wire-format-inconsistency-upd.h b/src/auditor/taler-auditor-httpd_wire-format-inconsistency-upd.h deleted file mode 100644 index 4ebf5b5ec..000000000 --- a/src/auditor/taler-auditor-httpd_wire-format-inconsistency-upd.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_WIRE_FORMAT_INCONSISTENCY_UPD_H -#define SRC_TALER_AUDITOR_HTTPD_WIRE_FORMAT_INCONSISTENCY_UPD_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -MHD_RESULT -TAH_WIRE_FORMAT_INCONSISTENCY_handler_update (struct TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif // SRC_TALER_AUDITOR_HTTPD_WIRE_FORMAT_INCONSISTENCY_UPD_H diff --git a/src/auditor/taler-auditor-httpd_wire-out-inconsistency-del.c b/src/auditor/taler-auditor-httpd_wire-out-inconsistency-del.c deleted file mode 100644 index b28eb9699..000000000 --- a/src/auditor/taler-auditor-httpd_wire-out-inconsistency-del.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - 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-auditor-httpd_wire-out-inconsistency-del.h" - - -MHD_RESULT -TAH_WIRE_OUT_INCONSISTENCY_handler_delete (struct TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - - enum GNUNET_DB_QueryStatus qs; - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - - // execute the transaction - qs = TAH_plugin->delete_wire_out_inconsistency (TAH_plugin->cls, - row_id); - - if (0 == qs) - { - // goes in here if there was an error with the transaction - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - TALER_LOG_WARNING ( - "Failed to handle DELETE /wire-out-inconsistency/ %s", - args[1]); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "row could not be found"); - - } - - // on success? - return TALER_MHD_REPLY_JSON_PACK (connection, - MHD_HTTP_NO_CONTENT, - GNUNET_JSON_pack_string ("status", - "WIRE_OUT_INCONSISTENCY_OK")); - -} diff --git a/src/auditor/taler-auditor-httpd_wire-out-inconsistency-del.h b/src/auditor/taler-auditor-httpd_wire-out-inconsistency-del.h deleted file mode 100644 index 54db5ef55..000000000 --- a/src/auditor/taler-auditor-httpd_wire-out-inconsistency-del.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_WIRE_OUT_INCONSISTENCY_DEL_H -#define SRC_TALER_AUDITOR_HTTPD_WIRE_OUT_INCONSISTENCY_DEL_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -/** - * Initialize subsystem. - */ -void -TEAH_WIRE_OUT_INCONSISTENCY_DELETE_init (void); - -/** - * Shut down subsystem. - */ -void -TEAH_WIRE_OUT_INCONSISTENCY_DELETE_done (void); - -/** - * Handle a "/wire-out-inconsistency" request. Parses the JSON, and, if - * successful, checks the signatures and stores the result in the DB. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @param args NULL-terminated array of remaining parts of the URI broken up at '/' - * @return MHD result code - */ -MHD_RESULT -TAH_WIRE_OUT_INCONSISTENCY_handler_delete ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - - -#endif diff --git a/src/auditor/taler-auditor-httpd_wire-out-inconsistency-get.c b/src/auditor/taler-auditor-httpd_wire-out-inconsistency-get.c index 63bcc854b..c7cddceb2 100644 --- a/src/auditor/taler-auditor-httpd_wire-out-inconsistency-get.c +++ b/src/auditor/taler-auditor-httpd_wire-out-inconsistency-get.c @@ -13,8 +13,6 @@ You should have 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 "platform.h" #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_json_lib.h> @@ -26,38 +24,41 @@ #include "taler-auditor-httpd.h" #include "taler-auditor-httpd_wire-out-inconsistency-get.h" + /** -* Add wire-out-inconsistency to the list. -* -* @param[in,out] cls a `json_t *` array to extend -* @param serial_id location of the @a dc in the database -* @param dc struct of inconsistencies -* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating -*/ + * Add wire-out-inconsistency to the list. + * + * @param[in,out] cls a `json_t *` array to extend + * @param dc struct of inconsistencies + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ static enum GNUNET_GenericReturnValue process_wire_out_inconsistency ( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_WireOutInconsistency *dc) { json_t *list = cls; json_t *obj; obj = GNUNET_JSON_PACK ( - - GNUNET_JSON_pack_int64 ("row_id", serial_id), - GNUNET_JSON_pack_string ("destination_account", dc->destination_account), - TALER_JSON_pack_amount ("expected", &dc->expected), - TALER_JSON_pack_amount ("claimed", &dc->claimed), - GNUNET_JSON_pack_bool ("suppressed", dc->suppressed) - - + GNUNET_JSON_pack_int64 ("row_id", + dc->row_id), + GNUNET_JSON_pack_string ("destination_account", + dc->destination_account), + GNUNET_JSON_pack_int64 ("wire_out_row_id", + dc->wire_out_row_id), + GNUNET_JSON_pack_string ("diagnostic", + dc->diagnostic), + TALER_JSON_pack_amount ("expected", + &dc->expected), + TALER_JSON_pack_amount ("claimed", + &dc->claimed), + GNUNET_JSON_pack_bool ("suppressed", + dc->suppressed) ); GNUNET_break (0 == json_array_append_new (list, obj)); - - return GNUNET_OK; } @@ -73,6 +74,9 @@ TAH_WIRE_OUT_INCONSISTENCY_handler_get ( { json_t *ja; enum GNUNET_DB_QueryStatus qs; + int64_t limit = -20; + uint64_t offset; + enum TALER_EXCHANGE_YesNoAll return_suppressed; (void) rh; (void) connection_cls; @@ -87,39 +91,28 @@ TAH_WIRE_OUT_INCONSISTENCY_handler_get ( TALER_EC_GENERIC_DB_SETUP_FAILED, NULL); } - ja = json_array (); - GNUNET_break (NULL != ja); - - int64_t limit = -20; - uint64_t offset; - TALER_MHD_parse_request_snumber (connection, "limit", &limit); - if (limit < 0) offset = INT64_MAX; else offset = 0; - TALER_MHD_parse_request_number (connection, "offset", &offset); - bool return_suppressed = false; - const char *ret_s = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "return_suppressed"); - if (ret_s != NULL && strcmp (ret_s, "true") == 0) - { - return_suppressed = true; - } - + TALER_MHD_parse_request_yna (connection, + "return_suppressed", + false, + &return_suppressed); + ja = json_array (); + GNUNET_break (NULL != ja); qs = TAH_plugin->get_wire_out_inconsistency ( TAH_plugin->cls, limit, offset, - return_suppressed, + (TALER_EXCHANGE_YNA_NO != return_suppressed), &process_wire_out_inconsistency, ja); diff --git a/src/auditor/taler-auditor-httpd_wire-out-inconsistency-upd.c b/src/auditor/taler-auditor-httpd_wire-out-inconsistency-upd.c deleted file mode 100644 index 0f889f737..000000000 --- a/src/auditor/taler-auditor-httpd_wire-out-inconsistency-upd.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - 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 "platform.h" -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_json_lib.h> -#include <jansson.h> -#include <microhttpd.h> -#include <pthread.h> -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler-auditor-httpd.h" -#include "taler-auditor-httpd_wire-out-inconsistency-upd.h" - -MHD_RESULT -TAH_WIRE_OUT_INCONSISTENCY_handler_update ( - struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]) -{ - enum GNUNET_DB_QueryStatus qs; - - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - - uint64_t row_id; - - if (args[2] != NULL) - row_id = atoi (args[2]); - else - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no row id specified"); - - - struct TALER_AUDITORDB_Generic_Update gu; - - gu.row_id = row_id; - - struct GNUNET_JSON_Specification spec[] = { - - // GNUNET_JSON_spec_uint64 ("row_id", &gu.row_id), - GNUNET_JSON_spec_bool ("suppressed", &gu.suppressed), - - GNUNET_JSON_spec_end () - }; - - json_t *json; - - (void) rh; - (void) connection_cls; - (void) upload_data; - (void) upload_data_size; - { - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_post_json (connection, - connection_cls, - upload_data, - upload_data_size, - &json); - if (GNUNET_SYSERR == res) - return MHD_NO; - if ((GNUNET_NO == res) || - (NULL == json)) - return MHD_YES; - res = TALER_MHD_parse_json_data (connection, - json, - spec); - if (GNUNET_SYSERR == res) - { - json_decref (json); - return MHD_NO; /* hard failure */ - } - if (GNUNET_NO == res) - { - json_decref (json); - return MHD_YES; /* failure */ - } - } - - /* execute transaction */ - qs = TAH_plugin->update_wire_out_inconsistency (TAH_plugin->cls, &gu); - - GNUNET_JSON_parse_free (spec); - json_decref (json); - - MHD_RESULT ret = MHD_NO; - - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "update_account"); - break; - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "unexpected serialization problem"); - break; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_AUDITOR_RESOURCE_NOT_FOUND, - "no updates executed"); - break; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - ret = TALER_MHD_reply_static (connection, - MHD_HTTP_NO_CONTENT, - NULL, - NULL, - 0); - break; - } - - return ret; -} diff --git a/src/auditor/taler-auditor-httpd_wire-out-inconsistency-upd.h b/src/auditor/taler-auditor-httpd_wire-out-inconsistency-upd.h deleted file mode 100644 index 6b48d6a0e..000000000 --- a/src/auditor/taler-auditor-httpd_wire-out-inconsistency-upd.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - 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 SRC_TALER_AUDITOR_HTTPD_WIRE_OUT_INCONSISTENCY_UPD_H -#define SRC_TALER_AUDITOR_HTTPD_WIRE_OUT_INCONSISTENCY_UPD_H - - -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - -MHD_RESULT -TAH_WIRE_OUT_INCONSISTENCY_handler_update (struct TAH_RequestHandler *rh, - struct MHD_Connection * - connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - const char *const args[]); - -#endif // SRC_TALER_AUDITOR_HTTPD_WIRE_OUT_INCONSISTENCY_UPD_H diff --git a/src/auditor/taler-helper-auditor-aggregation.c b/src/auditor/taler-helper-auditor-aggregation.c index 0011e3607..fcb9491c3 100644 --- a/src/auditor/taler-helper-auditor-aggregation.c +++ b/src/auditor/taler-helper-auditor-aggregation.c @@ -35,8 +35,6 @@ static int global_ret; /** * Run in test mode. Exit when idle instead of * going to sleep and waiting for more work. - * - * FIXME: not yet implemented! */ static int test_mode; @@ -111,8 +109,9 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg; * profitable for the exchange for this operation, * -1 if @a exchange being smaller than @a auditor is * profitable for the exchange, and 0 if it is unclear + * @return transaction status */ -static void +static enum GNUNET_DB_QueryStatus report_amount_arithmetic_inconsistency ( const char *operation, uint64_t rowid, @@ -141,13 +140,14 @@ report_amount_arithmetic_inconsistency ( } { - enum GNUNET_DB_QueryStatus qs; struct TALER_AUDITORDB_AmountArithmeticInconsistency aai = { + .problem_row_id = rowid, .profitable = profitable, .operation = (char *) operation, .exchange_amount = *exchange, .auditor_amount = *auditor }; + enum GNUNET_DB_QueryStatus qs; qs = TALER_ARL_adb->insert_amount_arithmetic_inconsistency ( TALER_ARL_adb->cls, @@ -156,7 +156,7 @@ report_amount_arithmetic_inconsistency ( if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling + return qs; } } if (0 != profitable) @@ -168,6 +168,7 @@ report_amount_arithmetic_inconsistency ( target, &delta); } + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; } @@ -183,8 +184,9 @@ report_amount_arithmetic_inconsistency ( * profitable for the exchange for this operation, * -1 if @a exchange being smaller than @a auditor is * profitable for the exchange, and 0 if it is unclear + * @return transaction status */ -static void +static enum GNUNET_DB_QueryStatus report_coin_arithmetic_inconsistency ( const char *operation, const struct TALER_CoinSpendPublicKeyP *coin_pub, @@ -229,7 +231,7 @@ report_coin_arithmetic_inconsistency ( if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling + return qs; } } if (0 != profitable) @@ -241,6 +243,7 @@ report_coin_arithmetic_inconsistency ( target, &delta); } + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; } @@ -250,8 +253,9 @@ report_coin_arithmetic_inconsistency ( * @param table affected table * @param rowid affected row, 0 if row is missing * @param diagnostic message explaining the problem + * @return transaction status */ -static void +static enum GNUNET_DB_QueryStatus report_row_inconsistency (const char *table, uint64_t rowid, const char *diagnostic) @@ -270,8 +274,9 @@ report_row_inconsistency (const char *table, if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling + return qs; } + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; } @@ -385,9 +390,9 @@ struct WireCheckContext * @param tl_head head of transaction history to verify * @param[out] merchant_gain amount the coin contributes to the wire transfer to the merchant * @param[out] deposit_gain amount the coin contributes excluding refunds - * @return #GNUNET_OK on success, #GNUNET_SYSERR if the transaction must fail (hard error) + * @return database transaction status */ -static enum GNUNET_GenericReturnValue +static enum GNUNET_DB_QueryStatus check_transaction_history_for_deposit ( const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_PrivateContractHashP *h_contract_terms, @@ -452,7 +457,7 @@ check_transaction_history_for_deposit ( if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling + return qs; } } deposited = &tl->details.deposit->amount_with_fee; /* according to exchange*/ @@ -486,11 +491,13 @@ check_transaction_history_for_deposit ( fee_claimed)) { /* Disagreement in fee structure between auditor and exchange DB! */ - report_amount_arithmetic_inconsistency ("deposit fee", - 0, - fee_claimed, - &issue->fees.deposit, - 1); + qs = report_amount_arithmetic_inconsistency ("deposit fee", + 0, + fee_claimed, + &issue->fees.deposit, + 1); + if (0 > qs) + return qs; } break; case TALER_EXCHANGEDB_TT_MELT: @@ -508,11 +515,13 @@ check_transaction_history_for_deposit ( fee_claimed)) { /* Disagreement in fee structure between exchange and auditor */ - report_amount_arithmetic_inconsistency ("melt fee", - 0, - fee_claimed, - &issue->fees.refresh, - 1); + qs = report_amount_arithmetic_inconsistency ("melt fee", + 0, + fee_claimed, + &issue->fees.refresh, + 1); + if (0 > qs) + return qs; } break; } @@ -548,11 +557,13 @@ check_transaction_history_for_deposit ( fee_claimed)) { /* Disagreement in fee structure between exchange and auditor! */ - report_amount_arithmetic_inconsistency ("refund fee", - 0, - fee_claimed, - &issue->fees.refund, - 1); + qs = report_amount_arithmetic_inconsistency ("refund fee", + 0, + fee_claimed, + &issue->fees.refund, + 1); + if (0 > qs) + return qs; } break; } @@ -623,11 +634,13 @@ check_transaction_history_for_deposit ( fee_claimed)) { /* Disagreement in fee structure between exchange and auditor! */ - report_amount_arithmetic_inconsistency ("refund fee", - 0, - fee_claimed, - &issue->fees.refund, - 1); + qs = report_amount_arithmetic_inconsistency ("refund fee", + 0, + fee_claimed, + &issue->fees.refund, + 1); + if (0 > qs) + return qs; } break; } @@ -674,11 +687,13 @@ check_transaction_history_for_deposit ( &merchant_loss)) { /* refunds above deposits? Bad! */ - report_coin_arithmetic_inconsistency ("refund (merchant)", - coin_pub, - merchant_gain, - &merchant_loss, - 1); + qs = report_coin_arithmetic_inconsistency ("refund (merchant)", + coin_pub, + merchant_gain, + &merchant_loss, + 1); + if (0 > qs) + return qs; /* For the overall aggregation, we should not count this as a NEGATIVE contribution as that is not allowed; so let's count it as zero as that's the best we can do. */ @@ -704,11 +719,13 @@ check_transaction_history_for_deposit ( &refunds)) { /* refunds above expenditures? Bad! */ - report_coin_arithmetic_inconsistency ("refund (balance)", - coin_pub, - &expenditures, - &refunds, - 1); + qs = report_coin_arithmetic_inconsistency ("refund (balance)", + coin_pub, + &expenditures, + &refunds, + 1); + if (0 > qs) + return qs; } else { @@ -717,15 +734,15 @@ check_transaction_history_for_deposit ( &issue->value)) { /* spent > value */ - report_coin_arithmetic_inconsistency ("spend", - coin_pub, - &spent, - &issue->value, - -1); + qs = report_coin_arithmetic_inconsistency ("spend", + coin_pub, + &spent, + &issue->value, + -1); + if (0 > qs) + return qs; } } - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Final merchant gain after refunds is %s\n", TALER_amount2s (deposit_gain)); @@ -734,7 +751,7 @@ check_transaction_history_for_deposit ( TALER_B2S (coin_pub), TALER_amount2s (merchant_gain), GNUNET_h2s (&h_contract_terms->hash)); - return GNUNET_OK; + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; } @@ -780,25 +797,34 @@ wire_transfer_information_cb ( struct TALER_PaytoHashP hpt; uint64_t etag_out; + if (0 > wcc->qs) + return; TALER_payto_hash (account_pay_uri, &hpt); if (0 != GNUNET_memcmp (&hpt, h_payto)) { - report_row_inconsistency ("wire_targets", - rowid, - "h-payto does not match payto URI"); + qs = report_row_inconsistency ("wire_targets", + rowid, + "h-payto does not match payto URI"); + if (0 > qs) + { + wcc->qs = qs; + return; + } } /* Obtain coin's transaction history */ - /* TODO: could use 'start' mechanism to only fetch transactions + /* FIXME: could use 'start' mechanism to only fetch transactions we did not yet process, instead of going over them again and again.*/ { struct TALER_Amount balance; struct TALER_DenominationHashP h_denom_pub; + qs = TALER_ARL_edb->get_coin_transactions (TALER_ARL_edb->cls, + false, coin_pub, 0, 0, @@ -807,42 +833,62 @@ wire_transfer_information_cb ( &h_denom_pub, &tl); } - if ((qs < 0) || - (NULL == tl)) + if (0 > qs) { wcc->qs = qs; - report_row_inconsistency ("aggregation", - rowid, - "no transaction history for coin claimed in aggregation"); + TALER_ARL_edb->free_coin_transaction_list (TALER_ARL_edb->cls, + tl); + return; + } + if (NULL == tl) + { + qs = report_row_inconsistency ("aggregation", + rowid, + "no transaction history for coin claimed in aggregation"); + if (0 > qs) + wcc->qs = qs; return; } qs = TALER_ARL_edb->get_known_coin (TALER_ARL_edb->cls, coin_pub, &coin); - if (qs <= 0) + if (0 > qs) { - /* this should be a foreign key violation at this point! */ GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); wcc->qs = qs; - report_row_inconsistency ("aggregation", - rowid, - "could not get coin details for coin claimed in aggregation"); + return; + } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + { + /* this should be a foreign key violation at this point! */ + qs = report_row_inconsistency ("aggregation", + rowid, + "could not get coin details for coin claimed in aggregation"); + if (0 > qs) + wcc->qs = qs; TALER_ARL_edb->free_coin_transaction_list (TALER_ARL_edb->cls, tl); return; } qs = TALER_ARL_get_denomination_info_by_hash (&coin.denom_pub_hash, &issue); - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) + if (0 > qs) { + wcc->qs = qs; TALER_denom_sig_free (&coin.denom_sig); TALER_ARL_edb->free_coin_transaction_list (TALER_ARL_edb->cls, tl); - if (0 == qs) - report_row_inconsistency ("aggregation", - rowid, - "could not find denomination key for coin claimed in aggregation"); - else + return; + } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + { + TALER_denom_sig_free (&coin.denom_sig); + TALER_ARL_edb->free_coin_transaction_list (TALER_ARL_edb->cls, + tl); + qs = report_row_inconsistency ("aggregation", + rowid, + "could not find denomination key for coin claimed in aggregation"); + if (0 > qs) wcc->qs = qs; return; } @@ -854,7 +900,7 @@ wire_transfer_information_cb ( denom_pub)) { struct TALER_AUDITORDB_BadSigLosses bsl = { - .row_id = rowid, + .problem_row_id = rowid, .operation = "wire", .loss = *coin_value, .operation_specific_pub = coin.coin_pub.eddsa_pub @@ -866,35 +912,44 @@ wire_transfer_information_cb ( if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling + wcc->qs = qs; + TALER_denom_sig_free (&coin.denom_sig); + TALER_ARL_edb->free_coin_transaction_list (TALER_ARL_edb->cls, + tl); + return; } TALER_ARL_amount_add (&TALER_ARL_USE_AB (aggregation_total_bad_sig_loss), &TALER_ARL_USE_AB (aggregation_total_bad_sig_loss), coin_value); - TALER_denom_sig_free (&coin.denom_sig); - TALER_ARL_edb->free_coin_transaction_list (TALER_ARL_edb->cls, - tl); - report_row_inconsistency ("deposit", - rowid, - "coin denomination signature invalid"); - return; + qs = report_row_inconsistency ("deposit", + rowid, + "coin denomination signature invalid"); + if (0 > qs) + { + wcc->qs = qs; + TALER_denom_sig_free (&coin.denom_sig); + TALER_ARL_edb->free_coin_transaction_list (TALER_ARL_edb->cls, + tl); + return; + } } TALER_denom_sig_free (&coin.denom_sig); GNUNET_assert (NULL != issue); /* mostly to help static analysis */ /* Check transaction history to see if it supports aggregate valuation */ - if (GNUNET_OK != - check_transaction_history_for_deposit (coin_pub, - h_contract_terms, - merchant_pub, - issue, - tl, - &computed_value, - &total_deposit_without_refunds)) + qs = check_transaction_history_for_deposit ( + coin_pub, + h_contract_terms, + merchant_pub, + issue, + tl, + &computed_value, + &total_deposit_without_refunds); + if (0 > qs) { TALER_ARL_edb->free_coin_transaction_list (TALER_ARL_edb->cls, tl); - wcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + wcc->qs = qs; return; } TALER_ARL_edb->free_coin_transaction_list (TALER_ARL_edb->cls, @@ -910,14 +965,17 @@ wire_transfer_information_cb ( coin_value, deposit_fee)) { - wcc->qs = GNUNET_DB_STATUS_HARD_ERROR; - report_amount_arithmetic_inconsistency ( + qs = report_amount_arithmetic_inconsistency ( "aggregation (fee structure)", rowid, coin_value, deposit_fee, -1); - return; + if (0 > qs) + { + wcc->qs = qs; + return; + } } if (0 != TALER_amount_cmp (&total_deposit_without_refunds, @@ -926,21 +984,31 @@ wire_transfer_information_cb ( GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Expected coin contribution of %s to aggregate\n", TALER_amount2s (&coin_value_without_fee)); - report_amount_arithmetic_inconsistency ( + qs = report_amount_arithmetic_inconsistency ( "aggregation (contribution)", rowid, &coin_value_without_fee, &total_deposit_without_refunds, -1); + if (0 > qs) + { + wcc->qs = qs; + return; + } } } /* Check other details of wire transfer match */ if (0 != strcmp (account_pay_uri, wcc->payto_uri)) { - report_row_inconsistency ("aggregation", - rowid, - "target of outgoing wire transfer do not match hash of wire from deposit"); + qs = report_row_inconsistency ("aggregation", + rowid, + "target of outgoing wire transfer do not match hash of wire from deposit"); + if (0 > qs) + { + wcc->qs = qs; + return; + } } if (GNUNET_TIME_timestamp_cmp (exec_time, !=, @@ -948,9 +1016,14 @@ wire_transfer_information_cb ( { /* This should be impossible from database constraints */ GNUNET_break (0); - report_row_inconsistency ("aggregation", - rowid, - "date given in aggregate does not match wire transfer date"); + qs = report_row_inconsistency ("aggregation", + rowid, + "date given in aggregate does not match wire transfer date"); + if (0 > qs) + { + wcc->qs = qs; + return; + } } /* Add coin's contribution to total aggregate value */ @@ -1056,6 +1129,7 @@ get_wire_fee (struct AggregationContext *ac, wfi->start_date)) { struct TALER_AUDITORDB_FeeTimeInconsistency ftib = { + .problem_row_id = 0, /* FIXME: fetch above! */ .diagnostic = "start date before previous end date", .time = wfi->start_date.abs_time, .type = (char *) method @@ -1064,11 +1138,11 @@ get_wire_fee (struct AggregationContext *ac, qs = TALER_ARL_adb->insert_fee_time_inconsistency ( TALER_ARL_adb->cls, &ftib); - if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling + ac->qs = qs; + return NULL; } } if ((NULL != wfi->next) && @@ -1077,6 +1151,7 @@ get_wire_fee (struct AggregationContext *ac, wfi->end_date)) { struct TALER_AUDITORDB_FeeTimeInconsistency ftia = { + .problem_row_id = 0, /* FIXME: fetch above! */ .diagnostic = "end date date after next start date", .time = wfi->end_date.abs_time, .type = (char *) method @@ -1089,7 +1164,8 @@ get_wire_fee (struct AggregationContext *ac, if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling + ac->qs = qs; + return NULL; } } return &wfi->fees.wire; @@ -1135,9 +1211,11 @@ check_wire_out_cb (void *cls, GNUNET_TIME_timestamp2s (date)); if (NULL == (method = TALER_payto_get_method (payto_uri))) { - report_row_inconsistency ("wire_out", - rowid, - "specified wire address lacks method"); + qs = report_row_inconsistency ("wire_out", + rowid, + "specified wire address lacks method"); + if (0 > qs) + ac->qs = qs; return GNUNET_OK; } @@ -1178,6 +1256,11 @@ check_wire_out_cb (void *cls, wire_fee = get_wire_fee (ac, method, date); + if (0 > ac->qs) + { + GNUNET_free (method); + return GNUNET_SYSERR; + } if (NULL == wire_fee) { report_row_inconsistency ("wire-fee", @@ -1191,13 +1274,19 @@ check_wire_out_cb (void *cls, &wcc.total_deposits, wire_fee)) { - report_amount_arithmetic_inconsistency ( + qs = report_amount_arithmetic_inconsistency ( "wire out (fee structure)", rowid, &wcc.total_deposits, wire_fee, -1); /* If fee arithmetic fails, we just assume the fee is zero */ + if (0 > qs) + { + ac->qs = qs; + GNUNET_free (method); + return GNUNET_SYSERR; + } final_amount = wcc.total_deposits; } } @@ -1252,8 +1341,9 @@ check_wire_out_cb (void *cls, { struct TALER_AUDITORDB_WireOutInconsistency woi = { - .row_id = rowid, .destination_account = (char *) payto_uri, + .diagnostic = "aggregated amount does not match expectations", + .wire_out_row_id = rowid, .expected = final_amount, .claimed = *amount }; @@ -1265,7 +1355,8 @@ check_wire_out_cb (void *cls, if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling + ac->qs = qs; + return GNUNET_SYSERR; } } return GNUNET_OK; @@ -1288,23 +1379,21 @@ analyze_aggregations (void *cls) { struct AggregationContext ac; struct WireFeeInfo *wfi; - enum GNUNET_DB_QueryStatus qsx; enum GNUNET_DB_QueryStatus qs; - enum GNUNET_DB_QueryStatus qsp; (void) cls; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Analyzing aggregations\n"); - qsp = TALER_ARL_adb->get_auditor_progress ( + qs = TALER_ARL_adb->get_auditor_progress ( TALER_ARL_adb->cls, TALER_ARL_GET_PP (aggregation_last_wire_out_serial_id), NULL); - if (0 > qsp) + if (0 > qs) { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsp); - return qsp; + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; } - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qsp) + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) { GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "First analysis using this auditor, starting audit from scratch\n"); @@ -1320,7 +1409,7 @@ analyze_aggregations (void *cls) memset (&ac, 0, sizeof (ac)); - qsx = TALER_ARL_adb->get_balance ( + qs = TALER_ARL_adb->get_balance ( TALER_ARL_adb->cls, TALER_ARL_GET_AB (aggregation_total_wire_fee_revenue), TALER_ARL_GET_AB (aggregation_total_arithmetic_delta_plus), @@ -1330,11 +1419,12 @@ analyze_aggregations (void *cls) TALER_ARL_GET_AB (aggregation_total_wire_out_delta_minus), TALER_ARL_GET_AB (aggregation_total_coin_delta_plus), NULL); - if (0 > qsx) + if (0 > qs) { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsx); - return qsx; + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; } + ac.qs = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; qs = TALER_ARL_edb->select_wire_out_above_serial_id ( TALER_ARL_edb->cls, @@ -1356,6 +1446,8 @@ analyze_aggregations (void *cls) if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) { /* there were no wire out entries to be looked at, we are done */ + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "No wire out entries found\n"); return qs; } if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != ac.qs) @@ -1363,34 +1455,38 @@ analyze_aggregations (void *cls) GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == ac.qs); return ac.qs; } - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qsx) - { - qs = TALER_ARL_adb->insert_balance ( - TALER_ARL_adb->cls, - TALER_ARL_SET_AB (aggregation_total_wire_fee_revenue), - TALER_ARL_SET_AB (aggregation_total_arithmetic_delta_plus), - TALER_ARL_SET_AB (aggregation_total_arithmetic_delta_minus), - TALER_ARL_SET_AB (aggregation_total_bad_sig_loss), - TALER_ARL_SET_AB (aggregation_total_wire_out_delta_plus), - TALER_ARL_SET_AB (aggregation_total_wire_out_delta_minus), - TALER_ARL_SET_AB (aggregation_total_coin_delta_plus), - NULL); - } - else + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Finished aggregation audit at %llu\n", + (unsigned long long) TALER_ARL_USE_PP ( + aggregation_last_wire_out_serial_id)); + qs = TALER_ARL_adb->insert_balance ( + TALER_ARL_adb->cls, + TALER_ARL_SET_AB (aggregation_total_wire_fee_revenue), + TALER_ARL_SET_AB (aggregation_total_arithmetic_delta_plus), + TALER_ARL_SET_AB (aggregation_total_arithmetic_delta_minus), + TALER_ARL_SET_AB (aggregation_total_bad_sig_loss), + TALER_ARL_SET_AB (aggregation_total_wire_out_delta_plus), + TALER_ARL_SET_AB (aggregation_total_wire_out_delta_minus), + TALER_ARL_SET_AB (aggregation_total_coin_delta_plus), + NULL); + if (0 > qs) { - GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qsx); - qs = TALER_ARL_adb->update_balance ( - TALER_ARL_adb->cls, - TALER_ARL_SET_AB (aggregation_total_wire_fee_revenue), - TALER_ARL_SET_AB (aggregation_total_arithmetic_delta_plus), - TALER_ARL_SET_AB (aggregation_total_arithmetic_delta_minus), - TALER_ARL_SET_AB (aggregation_total_bad_sig_loss), - TALER_ARL_SET_AB (aggregation_total_wire_out_delta_plus), - TALER_ARL_SET_AB (aggregation_total_wire_out_delta_minus), - TALER_ARL_SET_AB (aggregation_total_coin_delta_plus), - NULL); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Failed to update auditor DB, not recording progress\n"); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; } - if (0 >= qs) + qs = TALER_ARL_adb->update_balance ( + TALER_ARL_adb->cls, + TALER_ARL_SET_AB (aggregation_total_wire_fee_revenue), + TALER_ARL_SET_AB (aggregation_total_arithmetic_delta_plus), + TALER_ARL_SET_AB (aggregation_total_arithmetic_delta_minus), + TALER_ARL_SET_AB (aggregation_total_bad_sig_loss), + TALER_ARL_SET_AB (aggregation_total_wire_out_delta_plus), + TALER_ARL_SET_AB (aggregation_total_wire_out_delta_minus), + TALER_ARL_SET_AB (aggregation_total_coin_delta_plus), + NULL); + if (0 > qs) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Failed to update auditor DB, not recording progress\n"); @@ -1398,23 +1494,22 @@ analyze_aggregations (void *cls) return qs; } - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qsp) - { - qs = TALER_ARL_adb->insert_auditor_progress ( - TALER_ARL_adb->cls, - TALER_ARL_SET_PP (aggregation_last_wire_out_serial_id), - NULL); - } - else + qs = TALER_ARL_adb->insert_auditor_progress ( + TALER_ARL_adb->cls, + TALER_ARL_SET_PP (aggregation_last_wire_out_serial_id), + NULL); + if (0 > qs) { - GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qsp); - qs = TALER_ARL_adb->update_auditor_progress ( - TALER_ARL_adb->cls, - TALER_ARL_SET_PP (aggregation_last_wire_out_serial_id), - NULL); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Failed to update auditor DB, not recording progress\n"); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; } - - if (0 >= qs) + qs = TALER_ARL_adb->update_auditor_progress ( + TALER_ARL_adb->cls, + TALER_ARL_SET_PP (aggregation_last_wire_out_serial_id), + NULL); + if (0 > qs) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Failed to update auditor DB, not recording progress\n"); @@ -1566,10 +1661,6 @@ main (int argc, not do this, the linker may "optimize" libtalerutil away and skip #TALER_OS_init(), which we do need */ (void) TALER_project_data_default (); - if (GNUNET_OK != - GNUNET_STRINGS_get_utf8_args (argc, argv, - &argc, &argv)) - return EXIT_INVALIDARGUMENT; ret = GNUNET_PROGRAM_run ( argc, argv, @@ -1578,7 +1669,6 @@ main (int argc, options, &run, NULL); - GNUNET_free_nz ((void *) argv); if (GNUNET_SYSERR == ret) return EXIT_INVALIDARGUMENT; if (GNUNET_NO == ret) diff --git a/src/auditor/taler-helper-auditor-coins.c b/src/auditor/taler-helper-auditor-coins.c index f21d9fca4..8654d802e 100644 --- a/src/auditor/taler-helper-auditor-coins.c +++ b/src/auditor/taler-helper-auditor-coins.c @@ -46,8 +46,6 @@ static int global_ret; /** * Run in test mode. Exit when idle instead of * going to sleep and waiting for more work. - * - * FIXME: not yet implemented! */ static int test_mode; @@ -72,6 +70,7 @@ static TALER_ARL_DEF_AB (total_escrowed); static TALER_ARL_DEF_AB (coin_irregular_loss); static TALER_ARL_DEF_AB (coin_melt_fee_revenue); static TALER_ARL_DEF_AB (coin_deposit_fee_revenue); +static TALER_ARL_DEF_AB (coin_deposit_fee_loss); static TALER_ARL_DEF_AB (coin_refund_fee_revenue); static TALER_ARL_DEF_AB (total_recoup_loss); @@ -220,18 +219,14 @@ get_cached_history (const struct TALER_CoinSpendPublicKeyP *coin_pub) * @param issue denomination key where the loss was detected * @param risk maximum risk that might have just become real (coins created by this @a issue) * @param loss actual losses already (actualized before denomination was revoked) + * @return transaction status */ -static void +static enum GNUNET_DB_QueryStatus report_emergency_by_amount ( const struct TALER_EXCHANGEDB_DenominationKeyInformation *issue, const struct TALER_Amount *risk, const struct TALER_Amount *loss) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Reporting emergency on denomination `%s' over loss of %s\n", - GNUNET_h2s (&issue->denom_hash.hash), - TALER_amount2s (loss)); - enum GNUNET_DB_QueryStatus qs; struct TALER_AUDITORDB_Emergency emergency = { .denom_loss = *loss, @@ -242,14 +237,17 @@ report_emergency_by_amount ( .value = *&issue->value }; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Reporting emergency on denomination `%s' over loss of %s\n", + GNUNET_h2s (&issue->denom_hash.hash), + TALER_amount2s (loss)); qs = TALER_ARL_adb->insert_emergency ( TALER_ARL_adb->cls, &emergency); - if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling + return qs; } TALER_ARL_amount_add (&TALER_ARL_USE_AB ( coins_reported_emergency_risk_by_amount), @@ -259,6 +257,7 @@ report_emergency_by_amount ( TALER_ARL_amount_add (&TALER_ARL_USE_AB (coins_emergencies_loss), &TALER_ARL_USE_AB (coins_emergencies_loss), loss); + return qs; } @@ -275,8 +274,9 @@ report_emergency_by_amount ( * @param num_issued number of coins that were issued * @param num_known number of coins that have been deposited * @param risk amount that is at risk + * @return transaction status */ -static void +static enum GNUNET_DB_QueryStatus report_emergency_by_count ( const struct TALER_EXCHANGEDB_DenominationKeyInformation *issue, uint64_t num_issued, @@ -300,7 +300,7 @@ report_emergency_by_count ( if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling + return qs; } TALER_ARL_amount_add (&TALER_ARL_USE_AB ( coins_reported_emergency_risk_by_count), @@ -311,7 +311,7 @@ report_emergency_by_count ( TALER_ARL_amount_add (&TALER_ARL_USE_AB (coins_emergencies_loss_by_count), &TALER_ARL_USE_AB (coins_emergencies_loss_by_count), &issue->value); - + return qs; } @@ -329,8 +329,9 @@ report_emergency_by_count ( * representing a loss for the exchange); * -1 if @a exchange being smaller than @a auditor is * profitable for the exchange; and 0 if it is unclear + * @return transaction status */ -static void +static enum GNUNET_DB_QueryStatus report_amount_arithmetic_inconsistency ( const char *operation, uint64_t rowid, @@ -361,6 +362,7 @@ report_amount_arithmetic_inconsistency ( { struct TALER_AUDITORDB_AmountArithmeticInconsistency aai = { .profitable = profitable, + .problem_row_id = rowid, .operation = (char *) operation, .exchange_amount = *exchange, .auditor_amount = *auditor @@ -373,7 +375,7 @@ report_amount_arithmetic_inconsistency ( if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling! + return qs; } } if (0 != profitable) @@ -385,6 +387,7 @@ report_amount_arithmetic_inconsistency ( target, &delta); } + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; } @@ -394,8 +397,9 @@ report_amount_arithmetic_inconsistency ( * @param table affected table * @param rowid affected row, 0 if row is missing * @param diagnostic message explaining the problem + * @return transaction status */ -static void +static enum GNUNET_DB_QueryStatus report_row_inconsistency (const char *table, uint64_t rowid, const char *diagnostic) @@ -414,8 +418,9 @@ report_row_inconsistency (const char *table, if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling! + return qs; } + return qs; } @@ -447,13 +452,15 @@ check_coin_history (const struct TALER_CoinSpendPublicKeyP *coin_pub, bool have_refund; uint64_t etag_out; - /* TODO: could use 'etag' mechanism to only fetch transactions + /* FIXME: could use 'etag' mechanism to only fetch transactions we did not yet process, instead of going over them again and again. */ { struct TALER_Amount balance; struct TALER_DenominationHashP h_denom_pub; + qs = TALER_ARL_edb->get_coin_transactions (TALER_ARL_edb->cls, + false, coin_pub, 0, 0, @@ -462,8 +469,8 @@ check_coin_history (const struct TALER_CoinSpendPublicKeyP *coin_pub, &h_denom_pub, &tl); } - /*if (0 >= qs) - return qs;*/ + if (0 > qs) + return qs; GNUNET_assert (GNUNET_OK == TALER_amount_set_zero (value->currency, &refunded)); @@ -530,7 +537,7 @@ check_coin_history (const struct TALER_CoinSpendPublicKeyP *coin_pub, case TALER_EXCHANGEDB_TT_PURSE_REFUND: TALER_ARL_amount_add (&refunded, &refunded, - &tl->details.purse_refund->refund_amount); + &pos->details.purse_refund->refund_amount); TALER_ARL_amount_add (&spent, &spent, &pos->details.purse_refund->refund_fee); @@ -539,7 +546,7 @@ check_coin_history (const struct TALER_CoinSpendPublicKeyP *coin_pub, case TALER_EXCHANGEDB_TT_RESERVE_OPEN: TALER_ARL_amount_add (&spent, &spent, - &tl->details.reserve_open->coin_contribution); + &pos->details.reserve_open->coin_contribution); break; } /* switch (pos->type) */ } /* for (...) */ @@ -560,6 +567,7 @@ check_coin_history (const struct TALER_CoinSpendPublicKeyP *coin_pub, { /* spent > total: bad */ struct TALER_Amount loss; + TALER_ARL_amount_subtract (&loss, &spent, &total); @@ -567,11 +575,18 @@ check_coin_history (const struct TALER_CoinSpendPublicKeyP *coin_pub, "Loss detected for coin %s - %s\n", TALER_B2S (coin_pub), TALER_amount2s (&loss)); - report_amount_arithmetic_inconsistency (operation, - rowid, - &spent, - &total, - -1); + qs = report_amount_arithmetic_inconsistency (operation, + rowid, + &spent, + &total, + -1); + if (qs < 0) + { + TALER_ARL_edb->free_coin_transaction_list (TALER_ARL_edb->cls, + tl); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; + } } cache_history (coin_pub, tl); @@ -695,7 +710,7 @@ init_denomination (const struct TALER_DenominationHashP *denom_hash, GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); return qs; } - if (0 < qs) + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) { /* check revocation signature */ if (GNUNET_OK != @@ -704,9 +719,14 @@ init_denomination (const struct TALER_DenominationHashP *denom_hash, &TALER_ARL_master_pub, &msig)) { - report_row_inconsistency ("denomination revocations", - rowid, - "revocation signature invalid"); + qs = report_row_inconsistency ("denomination revocations", + rowid, + "revocation signature invalid"); + if (qs < 0) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; + } } else { @@ -714,8 +734,8 @@ init_denomination (const struct TALER_DenominationHashP *denom_hash, } } return ds->in_db - ? GNUNET_DB_STATUS_SUCCESS_ONE_RESULT - : GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; + ? GNUNET_DB_STATUS_SUCCESS_ONE_RESULT + : GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; } @@ -760,12 +780,13 @@ get_denomination_summary ( /** * Write information about the current knowledge about a denomination key * back to the database and update our global reporting data about the - * denomination. Also remove and free the memory of @a value. + * denomination. * * @param cls the `struct CoinContext` * @param denom_hash the hash of the denomination key * @param value a `struct DenominationSummary` * @return #GNUNET_OK (continue to iterate) + * #GNUNET_SYSERR (stop to iterate) */ static enum GNUNET_GenericReturnValue sync_denomination (void *cls, @@ -799,8 +820,14 @@ sync_denomination (void *cls, &denom_h); else qs = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; - if ((GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) && - (! TALER_amount_is_zero (&ds->dcd.denom_risk))) + if (qs < 0) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = qs; + return GNUNET_SYSERR; + } + if ( (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) && + (! TALER_amount_is_zero (&ds->dcd.denom_risk)) ) { /* The denomination expired and carried a balance; we can now book the remaining balance as profit, and reduce our risk @@ -814,25 +841,26 @@ sync_denomination (void *cls, this assertion fails, well, good luck: there is a bug in the auditor _or_ the auditor's database is corrupt. */ } - if ((GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) && - (! TALER_amount_is_zero (&ds->dcd.denom_balance))) + if ( (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) && + (! TALER_amount_is_zero (&ds->dcd.denom_balance)) ) { /* book denom_balance coin expiration profits! */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Denomination `%s' expired, booking %s in expiration profits\n", GNUNET_h2s (denom_hash), TALER_amount2s (&ds->dcd.denom_balance)); - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != - (qs = TALER_ARL_adb->insert_historic_denom_revenue ( - TALER_ARL_adb->cls, - &denom_h, - expire_deposit, - &ds->dcd.denom_balance, - &ds->dcd.recoup_loss))) + qs = TALER_ARL_adb->insert_historic_denom_revenue ( + TALER_ARL_adb->cls, + &denom_h, + expire_deposit, + &ds->dcd.denom_balance, + &ds->dcd.recoup_loss); + if (qs < 0) { /* Failed to store profits? Bad database */ GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); cc->qs = qs; + return GNUNET_SYSERR; } } } @@ -855,48 +883,78 @@ sync_denomination (void *cls, qs = (enum GNUNET_DB_QueryStatus) cnt; GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); cc->qs = qs; + return GNUNET_SYSERR; } - else + if (ds->dcd.num_issued < (uint64_t) cnt) { - if (ds->dcd.num_issued < (uint64_t) cnt) + /* more coins deposited than issued! very bad */ + qs = report_emergency_by_count (issue, + ds->dcd.num_issued, + cnt, + &ds->dcd.denom_risk); + if (qs < 0) { - /* more coins deposited than issued! very bad */ - report_emergency_by_count (issue, - ds->dcd.num_issued, - cnt, - &ds->dcd.denom_risk); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = qs; + return GNUNET_SYSERR; } - if (ds->report_emergency) + } + if (ds->report_emergency) + { + /* Value of coins deposited exceed value of coins + issued! Also very bad! */ + qs = report_emergency_by_amount (issue, + &ds->dcd.denom_risk, + &ds->dcd.denom_loss); + if (qs < 0) { - /* Value of coins deposited exceed value of coins - issued! Also very bad! */ - report_emergency_by_amount (issue, - &ds->dcd.denom_risk, - &ds->dcd.denom_loss); - + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = qs; + return GNUNET_SYSERR; } - if (ds->in_db) - qs = TALER_ARL_adb->update_denomination_balance (TALER_ARL_adb->cls, - &denom_h, - &ds->dcd); - else - qs = TALER_ARL_adb->insert_denomination_balance (TALER_ARL_adb->cls, - &denom_h, - &ds->dcd); + } + if (ds->in_db) + qs = TALER_ARL_adb->update_denomination_balance (TALER_ARL_adb->cls, + &denom_h, + &ds->dcd); + else + qs = TALER_ARL_adb->insert_denomination_balance (TALER_ARL_adb->cls, + &denom_h, + &ds->dcd); + + if (qs < 0) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = qs; + return GNUNET_SYSERR; } } - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) - { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - cc->qs = qs; - } + return GNUNET_OK; +} + + +/** + * Remove and free the memory of @a value from the + * denomination summaries. + * + * @param cls the `struct CoinContext` + * @param denom_hash the hash of the denomination key + * @param value a `struct DenominationSummary` + * @return #GNUNET_OK (continue to iterate) + */ +static enum GNUNET_GenericReturnValue +cleanup_denomination (void *cls, + const struct GNUNET_HashCode *denom_hash, + void *value) +{ + struct CoinContext *cc = cls; + struct DenominationSummary *ds = value; + GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (cc->denom_summaries, denom_hash, ds)); GNUNET_free (ds); - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != cc->qs) - return GNUNET_SYSERR; return GNUNET_OK; } @@ -951,20 +1009,25 @@ withdraw_cb (void *cls, qs = TALER_ARL_get_denomination_info (denom_pub, &issue, &dh); - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) - { - report_row_inconsistency ("withdraw", - rowid, - "denomination key not found"); - return GNUNET_OK; - } - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) + if (0 > qs) { - /* This really ought to be a transient DB error. */ GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); cc->qs = qs; return GNUNET_SYSERR; } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + { + qs = report_row_inconsistency ("withdraw", + rowid, + "denomination key not found"); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = qs; + return GNUNET_SYSERR; + } + return GNUNET_OK; + } ds = get_denomination_summary (cc, issue, &dh); @@ -1061,18 +1124,26 @@ reveal_data_cb (void *cls, /* lookup new coin denomination key */ qs = TALER_ARL_get_denomination_info_by_hash (&rrcs[i].h_denom_pub, &rctx->new_issues[i]); - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) - { - report_row_inconsistency ("refresh_reveal", - rctx->rowid, - "denomination key not found"); - rctx->err = GNUNET_NO; /* terminate here, but return "OK" to commit transaction */ - } - else if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) + if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); rctx->qs = qs; - rctx->err = GNUNET_SYSERR; /* terminate, return #GNUNET_SYSERR: abort transaction */ + rctx->err = GNUNET_SYSERR; + return; + } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + { + qs = report_row_inconsistency ("refresh_reveal", + rctx->rowid, + "denomination key not found"); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + rctx->qs = qs; + rctx->err = GNUNET_SYSERR; + return; + } + rctx->err = GNUNET_NO; } } } @@ -1135,6 +1206,7 @@ check_known_coin ( denom_pub)) { struct TALER_AUDITORDB_BadSigLosses bsl = { + .problem_row_id = rowid, .operation = (char *) operation, .loss = *loss_potential, .operation_specific_pub = coin_pub->eddsa_pub @@ -1146,7 +1218,7 @@ check_known_coin ( if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling! + return qs; } TALER_ARL_amount_add (&TALER_ARL_USE_AB (coin_irregular_loss), &TALER_ARL_USE_AB (coin_irregular_loss), @@ -1165,13 +1237,15 @@ check_known_coin ( * @param dso denomination summary to update * @param rowid responsible row (for logging) * @param amount_with_fee amount to subtract + * @return transaction status */ -static void +static enum GNUNET_DB_QueryStatus reduce_denom_balance (struct DenominationSummary *dso, uint64_t rowid, const struct TALER_Amount *amount_with_fee) { struct TALER_Amount tmp; + enum GNUNET_DB_QueryStatus qs; if (TALER_ARL_SR_INVALID_NEGATIVE == TALER_ARL_amount_subtract_neg (&tmp, @@ -1196,12 +1270,17 @@ reduce_denom_balance (struct DenominationSummary *dso, private key compromise). In that case, we cannot even subtract the profit we make from the fee from the escrow balance. Tested as part of test-auditor.sh, case #18 */ - report_amount_arithmetic_inconsistency ( + qs = report_amount_arithmetic_inconsistency ( "subtracting amount from escrow balance", rowid, &TALER_ARL_USE_AB (total_escrowed), amount_with_fee, 0); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; + } } else { @@ -1213,6 +1292,7 @@ reduce_denom_balance (struct DenominationSummary *dso, "New balance of denomination `%s' is %s\n", GNUNET_h2s (&dso->issue->denom_hash.hash), TALER_amount2s (&dso->dcd.denom_balance)); + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; } @@ -1258,31 +1338,38 @@ refresh_session_cb (void *cls, qs = TALER_ARL_get_denomination_info (denom_pub, &issue, NULL); - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) - { - report_row_inconsistency ("melt", - rowid, - "denomination key not found"); - return GNUNET_OK; - } - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) + if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); cc->qs = qs; return GNUNET_SYSERR; } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + { + qs = report_row_inconsistency ("melt", + rowid, + "denomination key not found"); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = qs; + return GNUNET_SYSERR; + } + return GNUNET_OK; + } qs = check_known_coin ("melt", issue, rowid, coin_pub, denom_pub, amount_with_fee); - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) + if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); cc->qs = qs; return GNUNET_SYSERR; } + /* verify melt signature */ { struct TALER_DenominationHashP h_denom_pub; @@ -1299,6 +1386,7 @@ refresh_session_cb (void *cls, coin_sig)) { struct TALER_AUDITORDB_BadSigLosses bsl = { + .problem_row_id = rowid, .operation = "melt", .loss = *amount_with_fee, .operation_specific_pub = coin_pub->eddsa_pub @@ -1311,7 +1399,8 @@ refresh_session_cb (void *cls, if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling + cc->qs = qs; + return GNUNET_SYSERR; } TALER_ARL_amount_add (&TALER_ARL_USE_AB (coin_irregular_loss), &TALER_ARL_USE_AB (coin_irregular_loss), @@ -1341,16 +1430,21 @@ refresh_session_cb (void *cls, cc->qs = GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_SYSERR; } - if ((GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) || - (0 == reveal_ctx.num_freshcoins)) + if (GNUNET_SYSERR == reveal_ctx.err) + { + cc->qs = reveal_ctx.qs; + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == cc->qs); + return GNUNET_SYSERR; + } + if ( (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) || + (0 == reveal_ctx.num_freshcoins) ) { /* This can legitimately happen if reveal was not yet called or only with invalid data, even if the exchange is correctly operating. We still report it. */ struct TALER_AUDITORDB_RefreshesHanging rh = { - .row_id = rowid, - .amount = *amount_with_fee, - .coin_pub = coin_pub->eddsa_pub + .problem_row_id = rowid, + .amount = *amount_with_fee }; qs = TALER_ARL_adb->insert_refreshes_hanging ( @@ -1359,21 +1453,18 @@ refresh_session_cb (void *cls, if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling! + cc->qs = qs; + return GNUNET_SYSERR; } TALER_ARL_amount_add (&TALER_ARL_USE_AB (total_refresh_hanging), &TALER_ARL_USE_AB (total_refresh_hanging), amount_with_fee); return GNUNET_OK; } - if (GNUNET_SYSERR == reveal_ctx.err) - cc->qs = reveal_ctx.qs; - if (GNUNET_OK != reveal_ctx.err) + if (GNUNET_NO == reveal_ctx.err) { GNUNET_free (reveal_ctx.new_issues); - if (GNUNET_SYSERR == reveal_ctx.err) - return GNUNET_SYSERR; return GNUNET_OK; } @@ -1404,11 +1495,17 @@ refresh_session_cb (void *cls, { /* Melt fee higher than contribution of melted coin; this makes no sense (exchange should never have accepted the operation) */ - report_amount_arithmetic_inconsistency ("melt contribution vs. fee", - rowid, - amount_with_fee, - &issue->fees.refresh, - -1); + qs = report_amount_arithmetic_inconsistency ("melt contribution vs. fee", + rowid, + amount_with_fee, + &issue->fees.refresh, + -1); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_SYSERR; + } /* To continue, best assumption is the melted coin contributed nothing (=> all withdrawal amounts will be counted as losses) */ GNUNET_assert (GNUNET_OK == @@ -1422,11 +1519,17 @@ refresh_session_cb (void *cls, { /* refresh_cost > amount_without_fee, which is bad (exchange lost) */ GNUNET_break_op (0); - report_amount_arithmetic_inconsistency ("melt (cost)", - rowid, - &amount_without_fee, /* 'exchange' */ - &refresh_cost, /* 'auditor' */ - 1); + qs = report_amount_arithmetic_inconsistency ("melt (cost)", + rowid, + &amount_without_fee, /* 'exchange' */ + &refresh_cost, /* 'auditor' */ + 1); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_SYSERR; + } } /* update outstanding denomination amounts for fresh coins withdrawn */ @@ -1441,9 +1544,15 @@ refresh_session_cb (void *cls, &ni->denom_hash); if (NULL == dsi) { - report_row_inconsistency ("refresh_reveal", - rowid, - "denomination key for fresh coin unknown to auditor"); + qs = report_row_inconsistency ("refresh_reveal", + rowid, + "denomination key for fresh coin unknown to auditor"); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_SYSERR; + } } else { @@ -1479,15 +1588,27 @@ refresh_session_cb (void *cls, &issue->denom_hash); if (NULL == dso) { - report_row_inconsistency ("refresh_reveal", - rowid, - "denomination key for dirty coin unknown to auditor"); + qs = report_row_inconsistency ("refresh_reveal", + rowid, + "denomination key for dirty coin unknown to auditor"); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_SYSERR; + } } else { - reduce_denom_balance (dso, - rowid, - amount_with_fee); + qs = reduce_denom_balance (dso, + rowid, + amount_with_fee); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_SYSERR; + } } /* update global melt fees */ @@ -1534,18 +1655,30 @@ deposit_cb (void *cls, NULL); if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) { - report_row_inconsistency ("deposits", - rowid, - "denomination key not found"); + qs = report_row_inconsistency ("deposits", + rowid, + "denomination key not found"); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_SYSERR; + } return GNUNET_OK; } if (GNUNET_TIME_timestamp_cmp (deposit->refund_deadline, >, deposit->wire_deadline)) { - report_row_inconsistency ("deposits", - rowid, - "refund deadline past wire deadline"); + qs = report_row_inconsistency ("deposits", + rowid, + "refund deadline past wire deadline"); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_SYSERR; + } } if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) @@ -1598,6 +1731,7 @@ deposit_cb (void *cls, &deposit->csig)) { struct TALER_AUDITORDB_BadSigLosses bsl = { + .problem_row_id = rowid, .operation = "deposit", .loss = deposit->amount_with_fee, .operation_specific_pub = deposit->coin.coin_pub.eddsa_pub @@ -1607,10 +1741,11 @@ deposit_cb (void *cls, TALER_ARL_adb->cls, &bsl); - if (qs < 0) + if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling! + cc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_SYSERR; } TALER_ARL_amount_add (&TALER_ARL_USE_AB (coin_irregular_loss), &TALER_ARL_USE_AB (coin_irregular_loss), @@ -1630,15 +1765,27 @@ deposit_cb (void *cls, &issue->denom_hash); if (NULL == ds) { - report_row_inconsistency ("deposit", - rowid, - "denomination key for deposited coin unknown to auditor"); + qs = report_row_inconsistency ("deposit", + rowid, + "denomination key for deposited coin unknown to auditor"); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_SYSERR; + } } else { - reduce_denom_balance (ds, - rowid, - &deposit->amount_with_fee); + qs = reduce_denom_balance (ds, + rowid, + &deposit->amount_with_fee); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_SYSERR; + } } /* update global deposit fees */ @@ -1691,18 +1838,25 @@ refund_cb (void *cls, qs = TALER_ARL_get_denomination_info (denom_pub, &issue, NULL); - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) - { - report_row_inconsistency ("refunds", - rowid, - "denomination key not found"); - return GNUNET_OK; - } - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) + if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_SYSERR; } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + { + qs = report_row_inconsistency ("refunds", + rowid, + "denomination key not found"); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_SYSERR; + } + return GNUNET_OK; + } /* verify refund signature */ if (GNUNET_OK != @@ -1714,6 +1868,7 @@ refund_cb (void *cls, merchant_sig)) { struct TALER_AUDITORDB_BadSigLosses bsl = { + .problem_row_id = rowid, .operation = "refund", .loss = *amount_with_fee, .operation_specific_pub = coin_pub->eddsa_pub @@ -1722,10 +1877,11 @@ refund_cb (void *cls, qs = TALER_ARL_adb->insert_bad_sig_losses ( TALER_ARL_adb->cls, &bsl); - if (qs < 0) + if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling + cc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_SYSERR; } TALER_ARL_amount_add (&TALER_ARL_USE_AB (coin_irregular_loss), &TALER_ARL_USE_AB (coin_irregular_loss), @@ -1738,11 +1894,17 @@ refund_cb (void *cls, amount_with_fee, &issue->fees.refund)) { - report_amount_arithmetic_inconsistency ("refund (fee)", - rowid, - &amount_without_fee, - &issue->fees.refund, - -1); + qs = report_amount_arithmetic_inconsistency ("refund (fee)", + rowid, + &amount_without_fee, + &issue->fees.refund, + -1); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_SYSERR; + } return GNUNET_OK; } @@ -1758,9 +1920,15 @@ refund_cb (void *cls, &issue->denom_hash); if (NULL == ds) { - report_row_inconsistency ("refund", - rowid, - "denomination key for refunded coin unknown to auditor"); + qs = report_row_inconsistency ("refund", + rowid, + "denomination key for refunded coin unknown to auditor"); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_SYSERR; + } } else { @@ -1787,9 +1955,9 @@ refund_cb (void *cls, &issue->fees.refund); if (full_refund) { - TALER_ARL_amount_subtract (&TALER_ARL_USE_AB (coin_deposit_fee_revenue), - &TALER_ARL_USE_AB (coin_deposit_fee_revenue), - &issue->fees.deposit); + TALER_ARL_amount_add (&TALER_ARL_USE_AB (coin_deposit_fee_loss), + &TALER_ARL_USE_AB (coin_deposit_fee_loss), + &issue->fees.deposit); } return GNUNET_OK; } @@ -1824,9 +1992,15 @@ purse_refund_coin_cb ( NULL); if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) { - report_row_inconsistency ("purse-refunds", - rowid, - "denomination key not found"); + qs = report_row_inconsistency ("purse-refunds", + rowid, + "denomination key not found"); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_SYSERR; + } return GNUNET_OK; } if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) @@ -1846,9 +2020,15 @@ purse_refund_coin_cb ( &issue->denom_hash); if (NULL == ds) { - report_row_inconsistency ("purse-refund", - rowid, - "denomination key for purse-refunded coin unknown to auditor"); + qs = report_row_inconsistency ("purse-refund", + rowid, + "denomination key for purse-refunded coin unknown to auditor"); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_SYSERR; + } } else { @@ -1870,9 +2050,9 @@ purse_refund_coin_cb ( TALER_amount2s (&ds->dcd.denom_balance)); } /* update total deposit fee balance */ - TALER_ARL_amount_subtract (&TALER_ARL_USE_AB (coin_deposit_fee_revenue), - &TALER_ARL_USE_AB (coin_deposit_fee_revenue), - &issue->fees.deposit); + TALER_ARL_amount_add (&TALER_ARL_USE_AB (coin_deposit_fee_loss), + &TALER_ARL_USE_AB (coin_deposit_fee_loss), + &issue->fees.deposit); return GNUNET_OK; } @@ -1952,29 +2132,36 @@ check_recoup (struct CoinContext *cc, &coin->coin_pub, coin_sig)) { - report_row_inconsistency (operation, - rowid, - "recoup signature invalid"); + qs = report_row_inconsistency (operation, + rowid, + "recoup signature invalid"); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_SYSERR; + } } if (GNUNET_OK != TALER_test_coin_valid (coin, denom_pub)) { struct TALER_AUDITORDB_BadSigLosses bsl = { + .problem_row_id = rowid, .operation = (char *) operation, .loss = *amount, - // TODO: maybe adding the wrong pub - bsl.operation_specific_pub = coin->coin_pub.eddsa_pub + .operation_specific_pub = coin->coin_pub.eddsa_pub }; qs = TALER_ARL_adb->insert_bad_sig_losses ( TALER_ARL_adb->cls, &bsl); - if (qs < 0) + if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling + cc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_SYSERR; } TALER_ARL_amount_add (&TALER_ARL_USE_AB (coin_irregular_loss), &TALER_ARL_USE_AB (coin_irregular_loss), @@ -1982,28 +2169,32 @@ check_recoup (struct CoinContext *cc, } qs = TALER_ARL_get_denomination_info_by_hash (&coin->denom_pub_hash, &issue); - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) - { - report_row_inconsistency (operation, - rowid, - "denomination key not found"); - return GNUNET_OK; - } - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) + if (0 > qs) { - /* The key not existing should be prevented by foreign key constraints, - so must be a transient DB error. */ GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - cc->qs = qs; + cc->qs = GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_SYSERR; } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + { + qs = report_row_inconsistency (operation, + rowid, + "denomination key not found"); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_SYSERR; + } + return GNUNET_OK; + } qs = check_known_coin (operation, issue, rowid, &coin->coin_pub, denom_pub, amount); - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) + if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); cc->qs = qs; @@ -2014,18 +2205,24 @@ check_recoup (struct CoinContext *cc, &issue->denom_hash); if (NULL == ds) { - report_row_inconsistency ("recoup", - rowid, - "denomination key for recouped coin unknown to auditor"); + qs = report_row_inconsistency ("recoup", + rowid, + "denomination key for recouped coin unknown to auditor"); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_SYSERR; + } } else { if (! ds->was_revoked) { struct TALER_AUDITORDB_BadSigLosses bsldnr = { + .problem_row_id = rowid, .operation = (char *) operation, .loss = *amount, - // TODO: hint missing? .operation_specific_pub = coin->coin_pub.eddsa_pub }; @@ -2036,7 +2233,8 @@ check_recoup (struct CoinContext *cc, if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling! + cc->qs = qs; + return GNUNET_SYSERR; } TALER_ARL_amount_add (&TALER_ARL_USE_AB (coin_irregular_loss), &TALER_ARL_USE_AB (coin_irregular_loss), @@ -2092,6 +2290,7 @@ recoup_cb (void *cls, coin_sig)) { struct TALER_AUDITORDB_BadSigLosses bsl = { + .problem_row_id = rowid, .operation = "recoup", .loss = *amount, .operation_specific_pub = coin->coin_pub.eddsa_pub @@ -2104,7 +2303,8 @@ recoup_cb (void *cls, if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling! + cc->qs = qs; + return GNUNET_SYSERR; } TALER_ARL_amount_add (&TALER_ARL_USE_AB (coin_irregular_loss), &TALER_ARL_USE_AB (coin_irregular_loss), @@ -2165,19 +2365,25 @@ recoup_refresh_cb (void *cls, /* Update old coin's denomination balance summary */ qs = TALER_ARL_get_denomination_info_by_hash (old_denom_pub_hash, &issue); - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS >= qs) + if (qs < 0) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = qs; + return GNUNET_SYSERR; + } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) { + qs = report_row_inconsistency ("refresh-recoup", + rowid, + "denomination key of old coin not found"); if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); cc->qs = qs; return GNUNET_SYSERR; } - report_row_inconsistency ("refresh-recoup", - rowid, - "denomination key of old coin not found"); } - else + { struct DenominationSummary *dso; @@ -2186,9 +2392,15 @@ recoup_refresh_cb (void *cls, old_denom_pub_hash); if (NULL == dso) { - report_row_inconsistency ("refresh_reveal", - rowid, - "denomination key for old coin unknown to auditor"); + qs = report_row_inconsistency ("refresh_reveal", + rowid, + "denomination key for old coin unknown to auditor"); + if (qs < 0) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = qs; + return GNUNET_SYSERR; + } } else { @@ -2209,6 +2421,7 @@ recoup_refresh_cb (void *cls, coin_sig)) { struct TALER_AUDITORDB_BadSigLosses bsl = { + .problem_row_id = rowid, .operation = "recoup-refresh", .loss = *amount, .operation_specific_pub = coin->coin_pub.eddsa_pub @@ -2217,11 +2430,11 @@ recoup_refresh_cb (void *cls, qs = TALER_ARL_adb->insert_bad_sig_losses ( TALER_ARL_adb->cls, &bsl); - if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling + cc->qs = qs; + return GNUNET_SYSERR; } TALER_ARL_amount_add (&TALER_ARL_USE_AB (coin_irregular_loss), &TALER_ARL_USE_AB (coin_irregular_loss), @@ -2245,7 +2458,7 @@ recoup_refresh_cb (void *cls, * denomination and to warn if there are denominations not approved * by this auditor. * - * @param cls closure, NULL + * @param cls closure, pointer to `enum GNUNET_DB_QueryStatus` * @param denom_pub public key, sometimes NULL (!) * @param issue issuing information with value, fees and other info about the denomination. */ @@ -2255,6 +2468,7 @@ check_denomination ( const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_EXCHANGEDB_DenominationKeyInformation *issue) { + enum GNUNET_DB_QueryStatus *iqs = cls; enum GNUNET_DB_QueryStatus qs; struct TALER_AuditorSignatureP auditor_sig; @@ -2266,8 +2480,9 @@ check_denomination ( &auditor_sig); if (0 > qs) { - GNUNET_break (0); - return; /* skip! */ + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + *iqs = qs; + return; } if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) { @@ -2308,9 +2523,11 @@ check_denomination ( if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling! + *iqs = qs; + return; } } + *iqs = qs; } @@ -2358,9 +2575,15 @@ purse_deposit_cb ( &dh); if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) { - report_row_inconsistency ("purse-deposits", - rowid, - "denomination key not found"); + qs = report_row_inconsistency ("purse-deposits", + rowid, + "denomination key not found"); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = qs; + return GNUNET_SYSERR; + } return GNUNET_OK; } qs = check_known_coin ("purse-deposit", @@ -2369,7 +2592,7 @@ purse_deposit_cb ( &deposit->coin_pub, denom_pub, &deposit->amount); - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) + if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); cc->qs = qs; @@ -2389,6 +2612,7 @@ purse_deposit_cb ( &deposit->coin_sig)) { struct TALER_AUDITORDB_BadSigLosses bsl = { + .problem_row_id = rowid, .operation = "purse-deposit", .loss = deposit->amount, .operation_specific_pub = deposit->coin_pub.eddsa_pub @@ -2397,11 +2621,11 @@ purse_deposit_cb ( qs = TALER_ARL_adb->insert_bad_sig_losses ( TALER_ARL_adb->cls, &bsl); - - if (qs < 0) + if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling! + cc->qs = qs; + return GNUNET_SYSERR; } TALER_ARL_amount_add (&TALER_ARL_USE_AB (coin_irregular_loss), &TALER_ARL_USE_AB (coin_irregular_loss), @@ -2415,15 +2639,27 @@ purse_deposit_cb ( &issue->denom_hash); if (NULL == ds) { - report_row_inconsistency ("purse-deposit", - rowid, - "denomination key for purse-deposited coin unknown to auditor"); + qs = report_row_inconsistency ("purse-deposit", + rowid, + "denomination key for purse-deposited coin unknown to auditor"); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = qs; + return GNUNET_SYSERR; + } } else { - reduce_denom_balance (ds, - rowid, - &deposit->amount); + qs = reduce_denom_balance (ds, + rowid, + &deposit->amount); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_SYSERR; + } } /* update global deposit fees */ @@ -2445,23 +2681,28 @@ analyze_coins (void *cls) { struct CoinContext cc; enum GNUNET_DB_QueryStatus qs; - enum GNUNET_DB_QueryStatus qsx; - enum GNUNET_DB_QueryStatus qsp; + enum GNUNET_DB_QueryStatus iqs; (void) cls; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking denominations...\n"); + iqs = GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; qs = TALER_ARL_edb->iterate_denomination_info (TALER_ARL_edb->cls, &check_denomination, - NULL); + &iqs); if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); return qs; } + if (0 > iqs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; + } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Analyzing coins\n"); - qsp = TALER_ARL_adb->get_auditor_progress ( + qs = TALER_ARL_adb->get_auditor_progress ( TALER_ARL_adb->cls, TALER_ARL_GET_PP (coins_withdraw_serial_id), TALER_ARL_GET_PP (coins_deposit_serial_id), @@ -2472,12 +2713,12 @@ analyze_coins (void *cls) TALER_ARL_GET_PP (coins_purse_deposits_serial_id), TALER_ARL_GET_PP (coins_purse_refunds_serial_id), NULL); - if (0 > qsp) + if (0 > qs) { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsp); - return qsp; + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; } - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qsp) + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) { GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "First analysis using this auditor, starting from scratch\n"); @@ -2507,13 +2748,14 @@ analyze_coins (void *cls) cc.qs = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; cc.denom_summaries = GNUNET_CONTAINER_multihashmap_create (256, GNUNET_NO); - qsx = TALER_ARL_adb->get_balance ( + qs = TALER_ARL_adb->get_balance ( TALER_ARL_adb->cls, TALER_ARL_GET_AB (coin_balance_risk), TALER_ARL_GET_AB (total_escrowed), TALER_ARL_GET_AB (coin_irregular_loss), TALER_ARL_GET_AB (coin_melt_fee_revenue), TALER_ARL_GET_AB (coin_deposit_fee_revenue), + TALER_ARL_GET_AB (coin_deposit_fee_loss), TALER_ARL_GET_AB (coin_refund_fee_revenue), TALER_ARL_GET_AB (total_recoup_loss), TALER_ARL_GET_AB (coins_total_arithmetic_delta_plus), @@ -2521,12 +2763,13 @@ analyze_coins (void *cls) TALER_ARL_GET_AB (coins_reported_emergency_risk_by_count), TALER_ARL_GET_AB (coins_reported_emergency_risk_by_amount), TALER_ARL_GET_AB (coins_emergencies_loss), + TALER_ARL_GET_AB (coins_emergencies_loss_by_count), TALER_ARL_GET_AB (total_refresh_hanging), NULL); - if (0 > qsx) + if (0 > qs) { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsx); - return qsx; + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; } /* process withdrawals */ if (0 > @@ -2541,12 +2784,12 @@ analyze_coins (void *cls) } if (0 > cc.qs) return cc.qs; - /* process refunds */ + /* process recoups */ if (0 > - (qs = TALER_ARL_edb->select_refunds_above_serial_id ( + (qs = TALER_ARL_edb->select_recoup_refresh_above_serial_id ( TALER_ARL_edb->cls, - TALER_ARL_USE_PP (coins_refund_serial_id), - &refund_cb, + TALER_ARL_USE_PP (coins_recoup_refresh_serial_id), + &recoup_refresh_cb, &cc))) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); @@ -2554,28 +2797,25 @@ analyze_coins (void *cls) } if (0 > cc.qs) return cc.qs; - /* process purse_refunds */ + /* process deposits */ if (0 > - (qs = TALER_ARL_edb->select_purse_decisions_above_serial_id ( + (qs = TALER_ARL_edb->select_coin_deposits_above_serial_id ( TALER_ARL_edb->cls, - TALER_ARL_USE_PP (coins_purse_refunds_serial_id), - true, /* only go for refunds! */ - &purse_refund_cb, + TALER_ARL_USE_PP (coins_deposit_serial_id), + &deposit_cb, &cc))) { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); return qs; } if (0 > cc.qs) return cc.qs; - - /* process recoups */ + /* process purse_deposits */ if (0 > - (qs = TALER_ARL_edb->select_recoup_refresh_above_serial_id ( + (qs = TALER_ARL_edb->select_purse_deposits_above_serial_id ( TALER_ARL_edb->cls, - TALER_ARL_USE_PP (coins_recoup_refresh_serial_id), - &recoup_refresh_cb, + TALER_ARL_USE_PP (coins_purse_deposits_serial_id), + &purse_deposit_cb, &cc))) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); @@ -2583,11 +2823,12 @@ analyze_coins (void *cls) } if (0 > cc.qs) return cc.qs; + /* process refunds */ if (0 > - (qs = TALER_ARL_edb->select_recoup_above_serial_id ( + (qs = TALER_ARL_edb->select_refunds_above_serial_id ( TALER_ARL_edb->cls, - TALER_ARL_USE_PP (coins_recoup_serial_id), - &recoup_cb, + TALER_ARL_USE_PP (coins_refund_serial_id), + &refund_cb, &cc))) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); @@ -2595,12 +2836,13 @@ analyze_coins (void *cls) } if (0 > cc.qs) return cc.qs; - /* process refreshes */ + /* process purse_refunds */ if (0 > - (qs = TALER_ARL_edb->select_refreshes_above_serial_id ( + (qs = TALER_ARL_edb->select_purse_decisions_above_serial_id ( TALER_ARL_edb->cls, - TALER_ARL_USE_PP (coins_melt_serial_id), - &refresh_session_cb, + TALER_ARL_USE_PP (coins_purse_refunds_serial_id), + true, /* only go for refunds! */ + &purse_refund_cb, &cc))) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); @@ -2608,12 +2850,12 @@ analyze_coins (void *cls) } if (0 > cc.qs) return cc.qs; - /* process deposits */ + /* process refreshes */ if (0 > - (qs = TALER_ARL_edb->select_coin_deposits_above_serial_id ( + (qs = TALER_ARL_edb->select_refreshes_above_serial_id ( TALER_ARL_edb->cls, - TALER_ARL_USE_PP (coins_deposit_serial_id), - &deposit_cb, + TALER_ARL_USE_PP (coins_melt_serial_id), + &refresh_session_cb, &cc))) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); @@ -2621,12 +2863,11 @@ analyze_coins (void *cls) } if (0 > cc.qs) return cc.qs; - /* process purse_deposits */ if (0 > - (qs = TALER_ARL_edb->select_purse_deposits_above_serial_id ( + (qs = TALER_ARL_edb->select_recoup_above_serial_id ( TALER_ARL_edb->cls, - TALER_ARL_USE_PP (coins_purse_deposits_serial_id), - &purse_deposit_cb, + TALER_ARL_USE_PP (coins_recoup_serial_id), + &recoup_cb, &cc))) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); @@ -2639,6 +2880,9 @@ analyze_coins (void *cls) GNUNET_CONTAINER_multihashmap_iterate (cc.denom_summaries, &sync_denomination, &cc); + GNUNET_CONTAINER_multihashmap_iterate (cc.denom_summaries, + &cleanup_denomination, + &cc); GNUNET_CONTAINER_multihashmap_destroy (cc.denom_summaries); if (0 > cc.qs) { @@ -2646,46 +2890,51 @@ analyze_coins (void *cls) return cc.qs; } - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qsx) + qs = TALER_ARL_adb->insert_balance ( + TALER_ARL_adb->cls, + TALER_ARL_SET_AB (coin_balance_risk), + TALER_ARL_SET_AB (total_escrowed), + TALER_ARL_SET_AB (coin_irregular_loss), + TALER_ARL_SET_AB (coin_melt_fee_revenue), + TALER_ARL_SET_AB (coin_deposit_fee_revenue), + TALER_ARL_SET_AB (coin_deposit_fee_loss), + TALER_ARL_SET_AB (coin_refund_fee_revenue), + TALER_ARL_SET_AB (total_recoup_loss), + TALER_ARL_SET_AB (coins_total_arithmetic_delta_plus), + TALER_ARL_SET_AB (coins_total_arithmetic_delta_minus), + TALER_ARL_SET_AB (coins_reported_emergency_risk_by_count), + TALER_ARL_SET_AB (coins_reported_emergency_risk_by_amount), + TALER_ARL_SET_AB (coins_emergencies_loss), + TALER_ARL_SET_AB (coins_emergencies_loss_by_count), + TALER_ARL_SET_AB (total_refresh_hanging), + NULL); + if (0 > qs) { - qs = TALER_ARL_adb->insert_balance ( - TALER_ARL_adb->cls, - TALER_ARL_SET_AB (coin_balance_risk), - TALER_ARL_SET_AB (total_escrowed), - TALER_ARL_SET_AB (coin_irregular_loss), - TALER_ARL_SET_AB (coin_melt_fee_revenue), - TALER_ARL_SET_AB (coin_deposit_fee_revenue), - TALER_ARL_SET_AB (coin_refund_fee_revenue), - TALER_ARL_SET_AB (total_recoup_loss), - TALER_ARL_SET_AB (coins_total_arithmetic_delta_plus), - TALER_ARL_SET_AB (coins_total_arithmetic_delta_minus), - TALER_ARL_SET_AB (coins_reported_emergency_risk_by_count), - TALER_ARL_SET_AB (coins_reported_emergency_risk_by_amount), - TALER_ARL_SET_AB (coins_emergencies_loss), - TALER_ARL_SET_AB (total_refresh_hanging), - NULL); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Failed to update auditor DB, not recording progress\n"); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; } - else - { - GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qsx); - qs = TALER_ARL_adb->update_balance ( - TALER_ARL_adb->cls, - TALER_ARL_SET_AB (coin_balance_risk), - TALER_ARL_SET_AB (total_escrowed), - TALER_ARL_SET_AB (coin_irregular_loss), - TALER_ARL_SET_AB (coin_melt_fee_revenue), - TALER_ARL_SET_AB (coin_deposit_fee_revenue), - TALER_ARL_SET_AB (coin_refund_fee_revenue), - TALER_ARL_SET_AB (total_recoup_loss), - TALER_ARL_SET_AB (coins_total_arithmetic_delta_plus), - TALER_ARL_SET_AB (coins_total_arithmetic_delta_minus), - TALER_ARL_SET_AB (coins_reported_emergency_risk_by_count), - TALER_ARL_SET_AB (coins_reported_emergency_risk_by_amount), - TALER_ARL_SET_AB (coins_emergencies_loss), - TALER_ARL_SET_AB (total_refresh_hanging), - NULL); - } - if (0 >= qs) + + qs = TALER_ARL_adb->update_balance ( + TALER_ARL_adb->cls, + TALER_ARL_SET_AB (coin_balance_risk), + TALER_ARL_SET_AB (total_escrowed), + TALER_ARL_SET_AB (coin_irregular_loss), + TALER_ARL_SET_AB (coin_melt_fee_revenue), + TALER_ARL_SET_AB (coin_deposit_fee_revenue), + TALER_ARL_SET_AB (coin_deposit_fee_loss), + TALER_ARL_SET_AB (coin_refund_fee_revenue), + TALER_ARL_SET_AB (total_recoup_loss), + TALER_ARL_SET_AB (coins_total_arithmetic_delta_plus), + TALER_ARL_SET_AB (coins_total_arithmetic_delta_minus), + TALER_ARL_SET_AB (coins_reported_emergency_risk_by_count), + TALER_ARL_SET_AB (coins_reported_emergency_risk_by_amount), + TALER_ARL_SET_AB (coins_emergencies_loss), + TALER_ARL_SET_AB (coins_emergencies_loss_by_count), + TALER_ARL_SET_AB (total_refresh_hanging), + NULL); + if (0 > qs) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Failed to update auditor DB, not recording progress\n"); @@ -2693,42 +2942,44 @@ analyze_coins (void *cls) return qs; } - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qsp) + qs = TALER_ARL_adb->insert_auditor_progress ( + TALER_ARL_adb->cls, + TALER_ARL_SET_PP (coins_withdraw_serial_id), + TALER_ARL_SET_PP (coins_deposit_serial_id), + TALER_ARL_SET_PP (coins_melt_serial_id), + TALER_ARL_SET_PP (coins_refund_serial_id), + TALER_ARL_SET_PP (coins_recoup_serial_id), + TALER_ARL_SET_PP (coins_recoup_refresh_serial_id), + TALER_ARL_SET_PP (coins_purse_deposits_serial_id), + TALER_ARL_SET_PP (coins_purse_refunds_serial_id), + NULL); + if (0 > qs) { - qs = TALER_ARL_adb->insert_auditor_progress ( - TALER_ARL_adb->cls, - TALER_ARL_SET_PP (coins_withdraw_serial_id), - TALER_ARL_SET_PP (coins_deposit_serial_id), - TALER_ARL_SET_PP (coins_melt_serial_id), - TALER_ARL_SET_PP (coins_refund_serial_id), - TALER_ARL_SET_PP (coins_recoup_serial_id), - TALER_ARL_SET_PP (coins_recoup_refresh_serial_id), - TALER_ARL_SET_PP (coins_purse_deposits_serial_id), - TALER_ARL_SET_PP (coins_purse_refunds_serial_id), - NULL); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Failed to update auditor DB, not recording progress\n"); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; } - else - { - GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qsp); - qs = TALER_ARL_adb->update_auditor_progress ( - TALER_ARL_adb->cls, - TALER_ARL_SET_PP (coins_withdraw_serial_id), - TALER_ARL_SET_PP (coins_deposit_serial_id), - TALER_ARL_SET_PP (coins_melt_serial_id), - TALER_ARL_SET_PP (coins_refund_serial_id), - TALER_ARL_SET_PP (coins_recoup_serial_id), - TALER_ARL_SET_PP (coins_recoup_refresh_serial_id), - TALER_ARL_SET_PP (coins_purse_deposits_serial_id), - TALER_ARL_SET_PP (coins_purse_refunds_serial_id), - NULL); - } - if (0 >= qs) + + qs = TALER_ARL_adb->update_auditor_progress ( + TALER_ARL_adb->cls, + TALER_ARL_SET_PP (coins_withdraw_serial_id), + TALER_ARL_SET_PP (coins_deposit_serial_id), + TALER_ARL_SET_PP (coins_melt_serial_id), + TALER_ARL_SET_PP (coins_refund_serial_id), + TALER_ARL_SET_PP (coins_recoup_serial_id), + TALER_ARL_SET_PP (coins_recoup_refresh_serial_id), + TALER_ARL_SET_PP (coins_purse_deposits_serial_id), + TALER_ARL_SET_PP (coins_purse_refunds_serial_id), + NULL); + if (0 > qs) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Failed to update auditor DB, not recording progress\n"); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); return qs; } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Concluded coin audit step at %llu/%llu/%llu/%llu/%llu/%llu/%llu\n", (unsigned long long) TALER_ARL_USE_PP (coins_deposit_serial_id), @@ -2878,10 +3129,6 @@ main (int argc, not do this, the linker may "optimize" libtalerutil away and skip #TALER_OS_init(), which we do need */ (void) TALER_project_data_default (); - if (GNUNET_OK != - GNUNET_STRINGS_get_utf8_args (argc, argv, - &argc, &argv)) - return EXIT_INVALIDARGUMENT; ret = GNUNET_PROGRAM_run ( argc, argv, @@ -2890,7 +3137,6 @@ main (int argc, options, &run, NULL); - GNUNET_free_nz ((void *) argv); if (GNUNET_SYSERR == ret) return EXIT_INVALIDARGUMENT; if (GNUNET_NO == ret) diff --git a/src/auditor/taler-helper-auditor-deposits.c b/src/auditor/taler-helper-auditor-deposits.c index e4a4dc597..dbe20487c 100644 --- a/src/auditor/taler-helper-auditor-deposits.c +++ b/src/auditor/taler-helper-auditor-deposits.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2016-2023 Taler Systems SA + Copyright (C) 2016-2024 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero Public License as published by the Free Software @@ -59,24 +59,18 @@ */ static int global_ret; +static TALER_ARL_DEF_PP (deposit_confirmation_serial_id); + /** * Run in test mode. Exit when idle instead of * going to sleep and waiting for more work. - * - * FIXME: not yet implemented! */ static int test_mode; /** - * Total number of deposit confirmations that we did not get. - */ -// FIXME: persist! -static json_int_t number_missed_deposit_confirmations; - -/** * Total amount involved in deposit confirmations that we did not get. */ -static struct TALER_Amount total_missed_deposit_confirmations; +static TALER_ARL_DEF_AB (total_missed_deposit_confirmations); /** * Should we run checks that only work for exchange-internal audits? @@ -91,64 +85,31 @@ static struct GNUNET_DB_EventHandler *eh; static const struct GNUNET_CONFIGURATION_Handle *cfg; /** - * Closure for #test_dc. + * Success or failure of (exchange) database operations within + * #test_dc. */ -struct DepositConfirmationContext -{ - - /** - * How many deposit confirmations did we NOT find in the #TALER_ARL_edb? - */ - unsigned long long missed_count; - - /** - * What is the total amount missing? - */ - struct TALER_Amount missed_amount; - - /** - * Lowest SerialID of the first coin we missed? (This is where we - * should resume next time). - */ - // uint64_t first_missed_coin_serial; - - /** - * Lowest SerialID of the first coin we missed? (This is where we - * should resume next time). - */ - // uint64_t last_seen_coin_serial; - - /** - * Success or failure of (exchange) database operations within - * #test_dc. - */ - enum GNUNET_DB_QueryStatus qs; +static enum GNUNET_DB_QueryStatus eqs; -}; /** * Given a deposit confirmation from #TALER_ARL_adb, check that it is also * in #TALER_ARL_edb. Update the deposit confirmation context accordingly. * * @param cls our `struct DepositConfirmationContext` - * @param serial_id row of the @a dc in the database * @param dc the deposit confirmation we know * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating */ static enum GNUNET_GenericReturnValue test_dc (void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_DepositConfirmation *dc) { - struct DepositConfirmationContext *dcc = cls; bool missing = false; - (void) cls; - enum GNUNET_DB_QueryStatus qs; - // dcc->last_seen_coin_serial = serial_id; + + (void) cls; + TALER_ARL_USE_PP (deposit_confirmation_serial_id) = dc->row_id; for (unsigned int i = 0; i < dc->num_coins; i++) { - struct GNUNET_TIME_Timestamp exchange_timestamp; struct TALER_Amount deposit_fee; @@ -160,38 +121,42 @@ test_dc (void *cls, dc->refund_deadline, &deposit_fee, &exchange_timestamp); - missing |= (0 == qs); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Status for deposit confirmation %llu-%u is %d\n", + (unsigned long long) dc->row_id, + i, + qs); + missing |= (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs); if (qs < 0) { GNUNET_break (0); /* DB error, complain */ - dcc->qs = qs; + eqs = qs; return GNUNET_SYSERR; } } - qs = TALER_ARL_adb->delete_deposit_confirmation (TALER_ARL_adb->cls, - serial_id); - if (qs < 0) - { - GNUNET_break (0); /* DB error, complain */ - dcc->qs = qs; - return GNUNET_SYSERR; - } - if (dcc->qs == 1) - { - (void) cls; - - } if (! missing) { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Deleting matching deposit confirmation %llu\n", + (unsigned long long) dc->row_id); + qs = TALER_ARL_adb->delete_generic ( + TALER_ARL_adb->cls, + TALER_AUDITORDB_DEPOSIT_CONFIRMATION, + dc->row_id); + if (qs < 0) + { + GNUNET_break (0); /* DB error, complain */ + eqs = qs; + return GNUNET_SYSERR; + } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found deposit %s in exchange database\n", GNUNET_h2s (&dc->h_contract_terms.hash)); return GNUNET_OK; /* all coins found, all good */ } - // dcc->first_missed_coin_serial = GNUNET_MIN (dcc->first_missed_coin_serial, serial_id); - dcc->missed_count++; - TALER_ARL_amount_add (&dcc->missed_amount, - &dcc->missed_amount, + // FIXME: where do we *decrease* this amount if we get a DC later? + TALER_ARL_amount_add (&TALER_ARL_USE_AB (total_missed_deposit_confirmations), + &TALER_ARL_USE_AB (total_missed_deposit_confirmations), &dc->total_without_fee); return GNUNET_OK; } @@ -207,23 +172,19 @@ test_dc (void *cls, static enum GNUNET_DB_QueryStatus analyze_deposit_confirmations (void *cls) { - // TALER_ARL_DEF_PP (deposit_confirmation_serial_id); - struct DepositConfirmationContext dcc; - // enum GNUNET_DB_QueryStatus qs; - enum GNUNET_DB_QueryStatus qsx; - // enum GNUNET_DB_QueryStatus qsp; + enum GNUNET_DB_QueryStatus qs; + (void) cls; -/* - qsp = TALER_ARL_adb->get_auditor_progress ( + qs = TALER_ARL_adb->get_auditor_progress ( TALER_ARL_adb->cls, TALER_ARL_GET_PP (deposit_confirmation_serial_id), NULL); - if (0 > qsp) + if (0 > qs) { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsp); - return qsp; + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; } - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qsp) + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) { GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "First analysis using deposit auditor, starting audit from scratch\n"); @@ -235,70 +196,79 @@ analyze_deposit_confirmations (void *cls) (unsigned long long) TALER_ARL_USE_PP ( deposit_confirmation_serial_id)); } -*/ - /* setup 'cc' */ - GNUNET_assert (GNUNET_OK == - TALER_amount_set_zero (TALER_ARL_currency, - &dcc.missed_amount)); - dcc.qs = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; - dcc.missed_count = 0LLU; - // dcc.first_missed_coin_serial = UINT64_MAX; - - qsx = TALER_ARL_adb->get_deposit_confirmations ( + qs = TALER_ARL_adb->get_balance ( + TALER_ARL_adb->cls, + TALER_ARL_GET_AB (total_missed_deposit_confirmations), + NULL); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; + } + qs = TALER_ARL_adb->get_deposit_confirmations ( TALER_ARL_adb->cls, INT64_MAX, 0, true, /* return suppressed */ &test_dc, - &dcc); - - - if (0 > qsx) + NULL); + if (0 > qs) { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsx); - return qsx; + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; + } + if (0 > eqs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == eqs); + return eqs; } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Analyzed %d deposit confirmations\n", - (int) qsx); - if (0 > dcc.qs) + (int) qs); + qs = TALER_ARL_adb->insert_auditor_progress ( + TALER_ARL_adb->cls, + TALER_ARL_SET_PP (deposit_confirmation_serial_id), + NULL); + if (0 > qs) { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == dcc.qs); - return dcc.qs; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Failed to update auditor DB, not recording progress\n"); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; + } + qs = TALER_ARL_adb->update_auditor_progress ( + TALER_ARL_adb->cls, + TALER_ARL_SET_PP (deposit_confirmation_serial_id), + NULL); + if (0 > qs) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Failed to update auditor DB, not recording progress\n"); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; + } + qs = TALER_ARL_adb->insert_balance ( + TALER_ARL_adb->cls, + TALER_ARL_SET_AB (total_missed_deposit_confirmations), + NULL); + if (0 > qs) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Failed to update auditor DB, not recording progress\n"); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; + } + qs = TALER_ARL_adb->update_balance ( + TALER_ARL_adb->cls, + TALER_ARL_SET_AB (total_missed_deposit_confirmations), + NULL); + if (0 > qs) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Failed to update auditor DB, not recording progress\n"); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; } -/* TODO: zu überprüfen - if (UINT64_MAX == dcc.first_missed_coin_serial) - ppdc.last_deposit_confirmation_serial_id = dcc.last_seen_coin_serial; - else - ppdc.last_deposit_confirmation_serial_id = dcc.first_missed_coin_serial - 1; - */ -/* sync 'cc' back to disk */ -/* - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qsp) - qs = TALER_ARL_adb->update_auditor_progress ( - TALER_ARL_adb->cls, - TALER_ARL_SET_PP (deposit_confirmation_serial_id), - NULL); - else - qs = TALER_ARL_adb->insert_auditor_progress ( - TALER_ARL_adb->cls, - TALER_ARL_SET_PP (deposit_confirmation_serial_id), - NULL); -*/ -// TODO :correct me and above -/* if (0 >= qs) { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Failed to update auditor DB, not recording progress\n"); - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - return qs; - }*/ - - number_missed_deposit_confirmations = (json_int_t) dcc.missed_count; - total_missed_deposit_confirmations = dcc.missed_amount; - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Concluded deposit confirmation audit"); - return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; } @@ -367,7 +337,6 @@ run (void *cls, (void) args; (void) cfgfile; cfg = c; - GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -437,10 +406,6 @@ main (int argc, not do this, the linker may "optimize" libtalerutil away and skip #TALER_OS_init(), which we do need */ (void) TALER_project_data_default (); - if (GNUNET_OK != - GNUNET_STRINGS_get_utf8_args (argc, argv, - &argc, &argv)) - return EXIT_INVALIDARGUMENT; ret = GNUNET_PROGRAM_run ( argc, argv, @@ -450,7 +415,6 @@ main (int argc, options, &run, NULL); - GNUNET_free_nz ((void *) argv); if (GNUNET_SYSERR == ret) return EXIT_INVALIDARGUMENT; if (GNUNET_NO == ret) diff --git a/src/auditor/taler-helper-auditor-purses.c b/src/auditor/taler-helper-auditor-purses.c index ad23d3e27..854cb8064 100644 --- a/src/auditor/taler-helper-auditor-purses.c +++ b/src/auditor/taler-helper-auditor-purses.c @@ -112,8 +112,9 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg; * profitable for the exchange for this operation, * -1 if @a exchange being smaller than @a auditor is * profitable for the exchange, and 0 if it is unclear + * @return transaction status */ -static void +static enum GNUNET_DB_QueryStatus report_amount_arithmetic_inconsistency ( const char *operation, uint64_t rowid, @@ -145,6 +146,7 @@ report_amount_arithmetic_inconsistency ( { struct TALER_AUDITORDB_AmountArithmeticInconsistency aai = { .profitable = profitable, + .problem_row_id = rowid, .operation = (char *) operation, .exchange_amount = *exchange, .auditor_amount = *auditor @@ -157,7 +159,7 @@ report_amount_arithmetic_inconsistency ( if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling! + return qs; } } @@ -170,6 +172,7 @@ report_amount_arithmetic_inconsistency ( target, &delta); } + return qs; } @@ -179,8 +182,9 @@ report_amount_arithmetic_inconsistency ( * @param table affected table * @param rowid affected row, 0 if row is missing * @param diagnostic message explaining the problem + * @return transaction status */ -static void +static enum GNUNET_DB_QueryStatus report_row_inconsistency (const char *table, uint64_t rowid, const char *diagnostic) @@ -199,8 +203,9 @@ report_row_inconsistency (const char *table, if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling! + return qs; } + return qs; } @@ -209,12 +214,13 @@ report_row_inconsistency (const char *table, * * @param atime when was the purse created * @param[out] fee set to the purse fee - * @return #GNUNET_OK on success + * @return #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT on success */ -static enum GNUNET_GenericReturnValue +static enum GNUNET_DB_QueryStatus get_purse_fee (struct GNUNET_TIME_Timestamp atime, struct TALER_Amount *fee) { + enum GNUNET_DB_QueryStatus qs; struct TALER_MasterSignatureP master_sig; struct GNUNET_TIME_Timestamp start_date; struct GNUNET_TIME_Timestamp end_date; @@ -223,30 +229,40 @@ get_purse_fee (struct GNUNET_TIME_Timestamp atime, struct GNUNET_TIME_Relative hexp; uint32_t pacl; - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != - TALER_ARL_edb->get_global_fee (TALER_ARL_edb->cls, - atime, - &start_date, - &end_date, - &fees, - &ptimeout, - &hexp, - &pacl, - &master_sig)) + qs = TALER_ARL_edb->get_global_fee (TALER_ARL_edb->cls, + atime, + &start_date, + &end_date, + &fees, + &ptimeout, + &hexp, + &pacl, + &master_sig); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; + } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) { char *diag; GNUNET_asprintf (&diag, "purse fee unavailable at %s\n", GNUNET_TIME_timestamp2s (atime)); - report_row_inconsistency ("purse-fee", - atime.abs_time.abs_value_us, - diag); + qs = report_row_inconsistency ("purse-fee", + atime.abs_time.abs_value_us, + diag); GNUNET_free (diag); - return GNUNET_SYSERR; + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; + } + return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; } *fee = fees.purse; - return GNUNET_OK; + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; } @@ -428,7 +444,9 @@ setup_purse (struct PurseContext *pc, pc->qs = qs; return NULL; } - if (0 > (qs = load_auditor_purse_summary (ps))) + GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs); + qs = load_auditor_purse_summary (ps); + if (0 > qs) { GNUNET_free (ps); pc->qs = qs; @@ -487,7 +505,7 @@ handle_purse_requested ( purse_sig)) { struct TALER_AUDITORDB_BadSigLosses bsl = { - .row_id = rowid, + .problem_row_id = rowid, .operation = "purse-request", .loss = *target_amount, .operation_specific_pub = purse_pub->eddsa_pub @@ -496,11 +514,11 @@ handle_purse_requested ( qs = TALER_ARL_adb->insert_bad_sig_losses ( TALER_ARL_adb->cls, &bsl); - if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling! + pc->qs = qs; + return GNUNET_SYSERR; } TALER_ARL_amount_add (&TALER_ARL_USE_AB (purse_total_bad_sig_loss), &TALER_ARL_USE_AB (purse_total_bad_sig_loss), @@ -586,9 +604,15 @@ handle_purse_deposits ( } if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) { - report_row_inconsistency ("purse-deposit", - rowid, - "denomination key not found"); + qs = report_row_inconsistency ("purse-deposit", + rowid, + "denomination key not found"); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + pc->qs = qs; + return GNUNET_SYSERR; + } return GNUNET_OK; } TALER_ARL_amount_subtract (&amount_minus_fee, @@ -606,7 +630,7 @@ handle_purse_deposits ( &deposit->coin_sig)) { struct TALER_AUDITORDB_BadSigLosses bsl = { - .row_id = rowid, + .problem_row_id = rowid, .operation = "purse-deposit", .loss = deposit->amount, .operation_specific_pub = deposit->coin_pub.eddsa_pub @@ -615,11 +639,11 @@ handle_purse_deposits ( qs = TALER_ARL_adb->insert_bad_sig_losses ( TALER_ARL_adb->cls, &bsl); - if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling! + pc->qs = qs; + return GNUNET_SYSERR; } TALER_ARL_amount_add (&TALER_ARL_USE_AB (purse_total_bad_sig_loss), &TALER_ARL_USE_AB (purse_total_bad_sig_loss), @@ -631,18 +655,22 @@ handle_purse_deposits ( &deposit->purse_pub); if (NULL == ps) { - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == pc->qs) + if (0 > pc->qs) { - report_row_inconsistency ("purse_deposit", - rowid, - "purse not found"); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == pc->qs); + return GNUNET_SYSERR; } - else + GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == pc->qs); + qs = report_row_inconsistency ("purse_deposit", + rowid, + "purse not found"); + if (0 > qs) { - /* Database trouble!? */ - GNUNET_break (0); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + pc->qs = qs; + return GNUNET_SYSERR; } - return GNUNET_SYSERR; + return GNUNET_OK; } TALER_ARL_amount_add (&ps->balance, &ps->balance, @@ -709,7 +737,7 @@ handle_purse_merged ( merge_sig)) { struct TALER_AUDITORDB_BadSigLosses bsl = { - .row_id = rowid, + .problem_row_id = rowid, .operation = "merge-purse", .loss = *amount, .operation_specific_pub = merge_pub->eddsa_pub @@ -719,11 +747,11 @@ handle_purse_merged ( qs = TALER_ARL_adb->insert_bad_sig_losses ( TALER_ARL_adb->cls, &bsl); - if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling! + pc->qs = qs; + return GNUNET_SYSERR; } TALER_ARL_amount_add (&TALER_ARL_USE_AB (purse_total_bad_sig_loss), &TALER_ARL_USE_AB (purse_total_bad_sig_loss), @@ -737,18 +765,22 @@ handle_purse_merged ( purse_pub); if (NULL == ps) { - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == pc->qs) + if (0 < pc->qs) { - report_row_inconsistency ("purse-merge", - rowid, - "purse not found"); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == pc->qs); + return GNUNET_SYSERR; } - else + GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == pc->qs); + qs = report_row_inconsistency ("purse-merge", + rowid, + "purse not found"); + if (qs < 0) { - /* Database trouble!? */ - GNUNET_break (0); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + pc->qs = qs; + return GNUNET_SYSERR; } - return GNUNET_SYSERR; + return GNUNET_OK; } GNUNET_break (0 == GNUNET_TIME_timestamp_cmp (merge_timestamp, @@ -796,6 +828,7 @@ handle_account_merged ( { struct PurseContext *pc = cls; struct PurseSummary *ps; + enum GNUNET_DB_QueryStatus qs; /* should be monotonically increasing */ GNUNET_assert (rowid >= TALER_ARL_USE_PP (purse_account_merge_serial_id)); @@ -812,9 +845,8 @@ handle_account_merged ( reserve_pub, reserve_sig)) { - enum GNUNET_DB_QueryStatus qs; struct TALER_AUDITORDB_BadSigLosses bsl = { - .row_id = rowid, + .problem_row_id = rowid, .operation = "account-merge", .loss = *purse_fee, .operation_specific_pub = reserve_pub->eddsa_pub @@ -823,11 +855,11 @@ handle_account_merged ( qs = TALER_ARL_adb->insert_bad_sig_losses ( TALER_ARL_adb->cls, &bsl); - if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling! + pc->qs = qs; + return GNUNET_SYSERR; } TALER_ARL_amount_add (&TALER_ARL_USE_AB (purse_total_bad_sig_loss), &TALER_ARL_USE_AB (purse_total_bad_sig_loss), @@ -838,18 +870,22 @@ handle_account_merged ( purse_pub); if (NULL == ps) { - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == pc->qs) + if (0 > pc->qs) { - report_row_inconsistency ("account-merge", - rowid, - "purse not found"); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == pc->qs); + return GNUNET_SYSERR; } - else + GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == pc->qs); + qs = report_row_inconsistency ("account-merge", + rowid, + "purse not found"); + if (0 > qs) { - /* Database trouble!? */ - GNUNET_break (0); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + pc->qs = qs; + return GNUNET_SYSERR; } - return GNUNET_SYSERR; + return GNUNET_OK; } TALER_ARL_amount_add (&TALER_ARL_USE_AB (purse_global_balance), &TALER_ARL_USE_AB (purse_global_balance), @@ -889,35 +925,46 @@ handle_purse_decision ( purse_pub); if (NULL == ps) { - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == pc->qs) + if (0 > pc->qs) { - report_row_inconsistency ("purse-decision", - rowid, - "purse not found"); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == pc->qs); + return GNUNET_SYSERR; } - else + qs = report_row_inconsistency ("purse-decision", + rowid, + "purse not found"); + if (0 > qs) { - /* Database trouble!? */ - GNUNET_break (0); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + pc->qs = qs; + return GNUNET_SYSERR; } - return GNUNET_SYSERR; + return GNUNET_OK; } - if (GNUNET_OK != - get_purse_fee (ps->creation_date, - &purse_fee)) + qs = get_purse_fee (ps->creation_date, + &purse_fee); + if (0 > qs) { - report_row_inconsistency ("purse-request", - rowid, - "purse fee unavailable"); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + pc->qs = qs; + return GNUNET_SYSERR; } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + return GNUNET_OK; /* already reported */ if (0 > TALER_amount_subtract (&balance_without_purse_fee, &ps->balance, &purse_fee)) { - report_row_inconsistency ("purse-request", - rowid, - "purse fee higher than balance"); + qs = report_row_inconsistency ("purse-request", + rowid, + "purse fee higher than balance"); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + pc->qs = qs; + return GNUNET_SYSERR; + } GNUNET_assert (GNUNET_OK == TALER_amount_set_zero (TALER_ARL_currency, &balance_without_purse_fee)); @@ -928,11 +975,17 @@ handle_purse_decision ( if (-1 != TALER_amount_cmp (&balance_without_purse_fee, &ps->total_value)) { - report_amount_arithmetic_inconsistency ("purse-decision: refund", - rowid, - &balance_without_purse_fee, - &ps->total_value, - 0); + qs = report_amount_arithmetic_inconsistency ("purse-decision: refund", + rowid, + &balance_without_purse_fee, + &ps->total_value, + 0); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + pc->qs = qs; + return GNUNET_SYSERR; + } } } else @@ -940,11 +993,17 @@ handle_purse_decision ( if (-1 == TALER_amount_cmp (&balance_without_purse_fee, &ps->total_value)) { - report_amount_arithmetic_inconsistency ("purse-decision: merge", - rowid, - &ps->total_value, - &balance_without_purse_fee, - 0); + qs = report_amount_arithmetic_inconsistency ("purse-decision: merge", + rowid, + &ps->total_value, + &balance_without_purse_fee, + 0); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + pc->qs = qs; + return GNUNET_SYSERR; + } TALER_ARL_amount_add (&TALER_ARL_USE_AB ( purse_total_balance_insufficient_loss), &TALER_ARL_USE_AB ( @@ -955,11 +1014,9 @@ handle_purse_decision ( qs = TALER_ARL_adb->delete_purse_info (TALER_ARL_adb->cls, purse_pub); - GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs); if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); pc->qs = qs; return GNUNET_SYSERR; } @@ -1006,7 +1063,8 @@ handle_purse_expired ( if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling! + pc->qs = qs; + return GNUNET_SYSERR; } TALER_ARL_amount_add (&TALER_ARL_USE_AB (purse_total_delayed_decisions), &TALER_ARL_USE_AB (purse_total_delayed_decisions), @@ -1033,10 +1091,8 @@ verify_purse_balance (void *cls, { struct PurseContext *pc = cls; struct PurseSummary *ps = value; - enum GNUNET_GenericReturnValue ret; enum GNUNET_DB_QueryStatus qs; - ret = GNUNET_OK; if (internal_checks) { struct TALER_Amount pf; @@ -1045,23 +1101,30 @@ verify_purse_balance (void *cls, /* subtract purse fee from ps->balance to get actual balance we expect, as we track the balance including purse fee, while the exchange subtracts the purse fee early on. */ - if (GNUNET_OK != - get_purse_fee (ps->creation_date, - &pf)) + qs = get_purse_fee (ps->creation_date, + &pf); + if (qs < 0) { - GNUNET_break (0); - report_row_inconsistency ("purse", - 0, - "purse fee unavailable"); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + pc->qs = qs; + return GNUNET_SYSERR; } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + return GNUNET_OK; /* error already reported */ if (0 > TALER_amount_subtract (&balance_without_purse_fee, &ps->balance, &pf)) { - report_row_inconsistency ("purse", - 0, - "purse fee higher than balance"); + qs = report_row_inconsistency ("purse", + 0, + "purse fee higher than balance"); + if (qs < 0) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + pc->qs = qs; + return GNUNET_SYSERR; + } GNUNET_assert (GNUNET_OK == TALER_amount_set_zero (TALER_ARL_currency, &balance_without_purse_fee)); @@ -1070,11 +1133,17 @@ verify_purse_balance (void *cls, if (0 != TALER_amount_cmp (&ps->exchange_balance, &balance_without_purse_fee)) { - report_amount_arithmetic_inconsistency ("purse-balance", - 0, - &ps->exchange_balance, - &balance_without_purse_fee, - 0); + qs = report_amount_arithmetic_inconsistency ("purse-balance", + 0, + &ps->exchange_balance, + &balance_without_purse_fee, + 0); + if (qs < 0) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + pc->qs = qs; + return GNUNET_SYSERR; + } } } @@ -1087,21 +1156,39 @@ verify_purse_balance (void *cls, &ps->purse_pub, &ps->balance, ps->expiration_date); - GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs); if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); pc->qs = qs; return GNUNET_SYSERR; } + GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs); + return GNUNET_OK; +} + + +/** + * Clear memory from the purses hash map. + * + * @param cls our `struct PurseContext` + * @param key hash of the purse public key + * @param value a `struct PurseSummary` + * @return #GNUNET_OK to process more entries + */ +static enum GNUNET_GenericReturnValue +release_purse_balance (void *cls, + const struct GNUNET_HashCode *key, + void *value) +{ + struct PurseContext *pc = cls; + struct PurseSummary *ps = value; GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (pc->purses, key, ps)); GNUNET_free (ps); - return ret; + return GNUNET_OK; } @@ -1115,14 +1202,12 @@ static enum GNUNET_DB_QueryStatus analyze_purses (void *cls) { struct PurseContext pc; - enum GNUNET_DB_QueryStatus qsx; enum GNUNET_DB_QueryStatus qs; - enum GNUNET_DB_QueryStatus qsp; (void) cls; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Analyzing purses\n"); - qsp = TALER_ARL_adb->get_auditor_progress ( + qs = TALER_ARL_adb->get_auditor_progress ( TALER_ARL_adb->cls, TALER_ARL_GET_PP (purse_account_merge_serial_id), TALER_ARL_GET_PP (purse_decision_serial_id), @@ -1131,12 +1216,12 @@ analyze_purses (void *cls) TALER_ARL_GET_PP (purse_request_serial_id), TALER_ARL_GET_PP (purse_open_counter), NULL); - if (0 > qsp) + if (0 > qs) { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsp); - return qsp; + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; } - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qsp) + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) { GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "First analysis using this auditor, starting audit from scratch\n"); @@ -1157,7 +1242,7 @@ analyze_purses (void *cls) purse_account_merge_serial_id)); } pc.qs = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; - qsx = TALER_ARL_adb->get_balance ( + qs = TALER_ARL_adb->get_balance ( TALER_ARL_adb->cls, TALER_ARL_GET_AB (purse_global_balance), TALER_ARL_GET_AB (purse_total_balance_insufficient_loss), @@ -1167,10 +1252,10 @@ analyze_purses (void *cls) TALER_ARL_GET_AB (purse_total_arithmetic_delta_minus), TALER_ARL_GET_AB (purse_total_bad_sig_loss), NULL); - if (qsx < 0) + if (qs < 0) { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsx); - return qsx; + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; } pc.purses = GNUNET_CONTAINER_multihashmap_create (512, GNUNET_NO); @@ -1185,6 +1270,11 @@ analyze_purses (void *cls) GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); return qs; } + if (pc.qs < 0) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == pc.qs); + return pc.qs; + } qs = TALER_ARL_edb->select_purse_merges_above_serial_id ( TALER_ARL_edb->cls, TALER_ARL_USE_PP (purse_merges_serial_id), @@ -1195,6 +1285,12 @@ analyze_purses (void *cls) GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); return qs; } + if (pc.qs < 0) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == pc.qs); + return pc.qs; + } + qs = TALER_ARL_edb->select_purse_deposits_above_serial_id ( TALER_ARL_edb->cls, TALER_ARL_USE_PP (purse_deposits_serial_id), @@ -1205,6 +1301,12 @@ analyze_purses (void *cls) GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); return qs; } + if (pc.qs < 0) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == pc.qs); + return pc.qs; + } + /* Charge purse fee! */ qs = TALER_ARL_edb->select_account_merges_above_serial_id ( TALER_ARL_edb->cls, @@ -1216,6 +1318,12 @@ analyze_purses (void *cls) GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); return qs; } + if (pc.qs < 0) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == pc.qs); + return pc.qs; + } + qs = TALER_ARL_edb->select_all_purse_decisions_above_serial_id ( TALER_ARL_edb->cls, TALER_ARL_USE_PP (purse_decision_serial_id), @@ -1226,6 +1334,12 @@ analyze_purses (void *cls) GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); return qs; } + if (pc.qs < 0) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == pc.qs); + return pc.qs; + } + qs = TALER_ARL_adb->select_purse_expired ( TALER_ARL_adb->cls, &handle_purse_expired, @@ -1235,75 +1349,90 @@ analyze_purses (void *cls) GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); return qs; } + if (pc.qs < 0) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == pc.qs); + return pc.qs; + } GNUNET_CONTAINER_multihashmap_iterate (pc.purses, &verify_purse_balance, &pc); + GNUNET_CONTAINER_multihashmap_iterate (pc.purses, + &release_purse_balance, + &pc); GNUNET_break (0 == GNUNET_CONTAINER_multihashmap_size (pc.purses)); GNUNET_CONTAINER_multihashmap_destroy (pc.purses); - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != pc.qs) - return qs; - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qsx) - { - qs = TALER_ARL_adb->insert_balance ( - TALER_ARL_adb->cls, - TALER_ARL_SET_AB (purse_global_balance), - TALER_ARL_SET_AB (purse_total_balance_insufficient_loss), - TALER_ARL_SET_AB (purse_total_delayed_decisions), - TALER_ARL_SET_AB (purse_total_balance_purse_not_closed), - TALER_ARL_SET_AB (purse_total_arithmetic_delta_plus), - TALER_ARL_SET_AB (purse_total_arithmetic_delta_minus), - TALER_ARL_SET_AB (purse_total_bad_sig_loss), - NULL); - } - else + if (pc.qs < 0) { - GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qsx); - qs = TALER_ARL_adb->update_balance ( - TALER_ARL_adb->cls, - TALER_ARL_SET_AB (purse_global_balance), - TALER_ARL_SET_AB (purse_total_balance_insufficient_loss), - TALER_ARL_SET_AB (purse_total_delayed_decisions), - TALER_ARL_SET_AB (purse_total_balance_purse_not_closed), - TALER_ARL_SET_AB (purse_total_arithmetic_delta_plus), - TALER_ARL_SET_AB (purse_total_arithmetic_delta_minus), - TALER_ARL_SET_AB (purse_total_bad_sig_loss), - NULL); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == pc.qs); + return pc.qs; } - if (0 >= qs) + + qs = TALER_ARL_adb->insert_balance ( + TALER_ARL_adb->cls, + TALER_ARL_SET_AB (purse_global_balance), + TALER_ARL_SET_AB (purse_total_balance_insufficient_loss), + TALER_ARL_SET_AB (purse_total_delayed_decisions), + TALER_ARL_SET_AB (purse_total_balance_purse_not_closed), + TALER_ARL_SET_AB (purse_total_arithmetic_delta_plus), + TALER_ARL_SET_AB (purse_total_arithmetic_delta_minus), + TALER_ARL_SET_AB (purse_total_bad_sig_loss), + NULL); + if (0 > qs) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Failed to update auditor DB, not recording progress\n"); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); return qs; } - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qsp) + + qs = TALER_ARL_adb->update_balance ( + TALER_ARL_adb->cls, + TALER_ARL_SET_AB (purse_global_balance), + TALER_ARL_SET_AB (purse_total_balance_insufficient_loss), + TALER_ARL_SET_AB (purse_total_delayed_decisions), + TALER_ARL_SET_AB (purse_total_balance_purse_not_closed), + TALER_ARL_SET_AB (purse_total_arithmetic_delta_plus), + TALER_ARL_SET_AB (purse_total_arithmetic_delta_minus), + TALER_ARL_SET_AB (purse_total_bad_sig_loss), + NULL); + if (0 > qs) { - qs = TALER_ARL_adb->insert_auditor_progress ( - TALER_ARL_adb->cls, - TALER_ARL_SET_PP (purse_account_merge_serial_id), - TALER_ARL_SET_PP (purse_decision_serial_id), - TALER_ARL_SET_PP (purse_deposits_serial_id), - TALER_ARL_SET_PP (purse_merges_serial_id), - TALER_ARL_SET_PP (purse_request_serial_id), - TALER_ARL_SET_PP (purse_open_counter), - NULL); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Failed to update auditor DB, not recording progress\n"); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; } - else + + qs = TALER_ARL_adb->insert_auditor_progress ( + TALER_ARL_adb->cls, + TALER_ARL_SET_PP (purse_account_merge_serial_id), + TALER_ARL_SET_PP (purse_decision_serial_id), + TALER_ARL_SET_PP (purse_deposits_serial_id), + TALER_ARL_SET_PP (purse_merges_serial_id), + TALER_ARL_SET_PP (purse_request_serial_id), + TALER_ARL_SET_PP (purse_open_counter), + NULL); + if (0 > qs) { - GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qsp); - qs = TALER_ARL_adb->update_auditor_progress ( - TALER_ARL_adb->cls, - TALER_ARL_SET_PP (purse_account_merge_serial_id), - TALER_ARL_SET_PP (purse_decision_serial_id), - TALER_ARL_SET_PP (purse_deposits_serial_id), - TALER_ARL_SET_PP (purse_merges_serial_id), - TALER_ARL_SET_PP (purse_request_serial_id), - TALER_ARL_SET_PP (purse_open_counter), - NULL); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Failed to update auditor DB, not recording progress\n"); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; } - if (0 >= qs) + + qs = TALER_ARL_adb->update_auditor_progress ( + TALER_ARL_adb->cls, + TALER_ARL_SET_PP (purse_account_merge_serial_id), + TALER_ARL_SET_PP (purse_decision_serial_id), + TALER_ARL_SET_PP (purse_deposits_serial_id), + TALER_ARL_SET_PP (purse_merges_serial_id), + TALER_ARL_SET_PP (purse_request_serial_id), + TALER_ARL_SET_PP (purse_open_counter), + NULL); + if (0 > qs) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Failed to update auditor DB, not recording progress\n"); @@ -1463,10 +1592,6 @@ main (int argc, not do this, the linker may "optimize" libtalerutil away and skip #TALER_OS_init(), which we do need */ (void) TALER_project_data_default (); - if (GNUNET_OK != - GNUNET_STRINGS_get_utf8_args (argc, argv, - &argc, &argv)) - return EXIT_INVALIDARGUMENT; ret = GNUNET_PROGRAM_run ( argc, argv, @@ -1475,7 +1600,6 @@ main (int argc, options, &run, NULL); - GNUNET_free_nz ((void *) argv); if (GNUNET_SYSERR == ret) return EXIT_INVALIDARGUMENT; if (GNUNET_NO == ret) diff --git a/src/auditor/taler-helper-auditor-reserves.c b/src/auditor/taler-helper-auditor-reserves.c index e58a094f9..3c8891d97 100644 --- a/src/auditor/taler-helper-auditor-reserves.c +++ b/src/auditor/taler-helper-auditor-reserves.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2016-2022 Taler Systems SA + Copyright (C) 2016-2024 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero Public License as published by the Free Software @@ -39,10 +39,13 @@ static int global_ret; /** + * State of the last database transaction. + */ +static enum GNUNET_DB_QueryStatus global_qs; + +/** * Run in test mode. Exit when idle instead of * going to sleep and waiting for more work. - * - * FIXME: not yet implemented! */ static int test_mode; @@ -167,7 +170,7 @@ report_amount_arithmetic_inconsistency ( { struct TALER_AUDITORDB_AmountArithmeticInconsistency aai = { - .row_id = rowid, + .problem_row_id = rowid, .profitable = profitable, .operation = (char *) operation, .exchange_amount = *exchange, @@ -181,7 +184,8 @@ report_amount_arithmetic_inconsistency ( if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling!!? + global_qs = qs; + return; } } @@ -223,7 +227,8 @@ report_row_inconsistency (const char *table, if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling!!? + global_qs = qs; + return; } } @@ -458,13 +463,14 @@ setup_reserve (struct ReserveContext *rc, * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop */ static enum GNUNET_GenericReturnValue -handle_reserve_in (void *cls, - uint64_t rowid, - const struct TALER_ReservePublicKeyP *reserve_pub, - const struct TALER_Amount *credit, - const char *sender_account_details, - uint64_t wire_reference, - struct GNUNET_TIME_Timestamp execution_date) +handle_reserve_in ( + void *cls, + uint64_t rowid, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_Amount *credit, + const char *sender_account_details, + uint64_t wire_reference, + struct GNUNET_TIME_Timestamp execution_date) { struct ReserveContext *rc = cls; struct ReserveSummary *rs; @@ -514,14 +520,15 @@ handle_reserve_in (void *cls, * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop */ static enum GNUNET_GenericReturnValue -handle_reserve_out (void *cls, - uint64_t rowid, - const struct TALER_BlindedCoinHashP *h_blind_ev, - const struct TALER_DenominationPublicKey *denom_pub, - 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) +handle_reserve_out ( + void *cls, + uint64_t rowid, + const struct TALER_BlindedCoinHashP *h_blind_ev, + const struct TALER_DenominationPublicKey *denom_pub, + 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) { struct ReserveContext *rc = cls; struct ReserveSummary *rs; @@ -555,6 +562,8 @@ handle_reserve_out (void *cls, report_row_inconsistency ("withdraw", rowid, "denomination key not found"); + if (global_qs < 0) + return GNUNET_SYSERR; return GNUNET_OK; } @@ -572,7 +581,7 @@ handle_reserve_out (void *cls, execution_date)) { struct TALER_AUDITORDB_DenominationKeyValidityWithdrawInconsistency dkvwi ={ - .row_id = rowid, + .problem_row_id = rowid, .execution_date = execution_date.abs_time, .denompub_h = *&h_denom_pub, .reserve_pub = *reserve_pub @@ -586,7 +595,8 @@ handle_reserve_out (void *cls, if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - /* FIXME: error handling! */ + rc->qs = qs; + return GNUNET_SYSERR; } } @@ -599,7 +609,7 @@ handle_reserve_out (void *cls, reserve_sig)) { struct TALER_AUDITORDB_BadSigLosses bsl = { - .row_id = rowid, + .problem_row_id = rowid, .operation = "withdraw", .loss = *amount_with_fee, .operation_specific_pub = reserve_pub->eddsa_pub @@ -612,7 +622,8 @@ handle_reserve_out (void *cls, if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling! + rc->qs = qs; + return GNUNET_SYSERR; } TALER_ARL_amount_add (&TALER_ARL_USE_AB (reserves_total_bad_sig_loss), &TALER_ARL_USE_AB (reserves_total_bad_sig_loss), @@ -630,6 +641,8 @@ handle_reserve_out (void *cls, report_row_inconsistency ("withdraw", rowid, "amount with fee from exchange does not match denomination value plus fee"); + if (global_qs < 0) + return GNUNET_SYSERR; } rs = setup_reserve (rc, reserve_pub); @@ -707,7 +720,7 @@ handle_recoup_by_reserve ( coin_sig)) { struct TALER_AUDITORDB_BadSigLosses bslr = { - .row_id = rowid, + .problem_row_id = rowid, .operation = "recoup", .loss = *amount, .operation_specific_pub = coin->coin_pub.eddsa_pub @@ -720,7 +733,8 @@ handle_recoup_by_reserve ( if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling! + rc->qs = qs; + return GNUNET_SYSERR; } TALER_ARL_amount_add (&TALER_ARL_USE_AB (reserves_total_bad_sig_loss), &TALER_ARL_USE_AB (reserves_total_bad_sig_loss), @@ -747,6 +761,8 @@ handle_recoup_by_reserve ( report_row_inconsistency ("recoup", rowid, "denomination key not in revocation set"); + if (global_qs < 0) + return GNUNET_SYSERR; TALER_ARL_amount_add (&TALER_ARL_USE_AB (reserves_reserve_loss), &TALER_ARL_USE_AB (reserves_reserve_loss), amount); @@ -783,7 +799,7 @@ handle_recoup_by_reserve ( "master signature invalid"))) { struct TALER_AUDITORDB_BadSigLosses bslrm = { - .row_id = rev_rowid, + .problem_row_id = rev_rowid, .operation = "recoup-master", .loss = *amount, .operation_specific_pub = TALER_ARL_master_pub.eddsa_pub @@ -796,6 +812,8 @@ handle_recoup_by_reserve ( if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + rc->qs = qs; + return GNUNET_SYSERR; } TALER_ARL_amount_add (&TALER_ARL_USE_AB (reserves_total_bad_sig_loss), &TALER_ARL_USE_AB (reserves_total_bad_sig_loss), @@ -927,7 +945,7 @@ handle_reserve_open ( reserve_sig)) { struct TALER_AUDITORDB_BadSigLosses bsl = { - .row_id = rowid, + .problem_row_id = rowid, .operation = "reserve-open", .loss = *reserve_payment, .operation_specific_pub = reserve_pub->eddsa_pub @@ -940,7 +958,8 @@ handle_reserve_open ( if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling! + rc->qs = qs; + return GNUNET_SYSERR; } TALER_ARL_amount_add (&TALER_ARL_USE_AB (reserves_total_bad_sig_loss), &TALER_ARL_USE_AB (reserves_total_bad_sig_loss), @@ -1027,6 +1046,8 @@ handle_reserve_closed ( closing_fee, &expected_fee, 1); + if (global_qs < 0) + return GNUNET_SYSERR; } } @@ -1062,6 +1083,8 @@ handle_reserve_closed ( report_row_inconsistency ("reserves_close", rowid, "reserve close request unknown"); + if (global_qs < 0) + return GNUNET_SYSERR; } else { @@ -1077,7 +1100,7 @@ handle_reserve_closed ( &reserve_sig)) { struct TALER_AUDITORDB_BadSigLosses bsl = { - .row_id = close_request_row, + .problem_row_id = close_request_row, .operation = "close-request", .loss = *amount_with_fee, .operation_specific_pub = reserve_pub->eddsa_pub @@ -1090,20 +1113,24 @@ handle_reserve_closed ( if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling! + rc->qs = qs; + GNUNET_free (payto_uri); + return GNUNET_SYSERR; } TALER_ARL_amount_add (&TALER_ARL_USE_AB (reserves_total_bad_sig_loss), &TALER_ARL_USE_AB (reserves_total_bad_sig_loss), amount_with_fee); } } - if ((NULL == payto_uri) && - (NULL == rs->sender_account)) + if ( (NULL == payto_uri) && + (NULL == rs->sender_account) ) { GNUNET_break (! rs->had_ri); report_row_inconsistency ("reserves_close", rowid, "target account not verified, auditor does not know reserve"); + if (global_qs < 0) + return GNUNET_SYSERR; } if (NULL == payto_uri) { @@ -1114,6 +1141,8 @@ handle_reserve_closed ( report_row_inconsistency ("reserves_close", rowid, "target account does not match origin account"); + if (global_qs < 0) + return GNUNET_SYSERR; } } else @@ -1124,6 +1153,11 @@ handle_reserve_closed ( report_row_inconsistency ("reserves_close", rowid, "target account does not match origin account"); + if (global_qs < 0) + { + GNUNET_free (payto_uri); + return GNUNET_SYSERR; + } } } GNUNET_free (payto_uri); @@ -1136,6 +1170,8 @@ handle_reserve_closed ( report_row_inconsistency ("reserves_close", rowid, "target account not verified, auditor does not know reserve"); + if (global_qs < 0) + return GNUNET_SYSERR; } else if (0 != strcmp (rs->sender_account, receiver_account)) @@ -1143,6 +1179,8 @@ handle_reserve_closed ( report_row_inconsistency ("reserves_close", rowid, "target account does not match origin account"); + if (global_qs < 0) + return GNUNET_SYSERR; } } @@ -1208,7 +1246,7 @@ handle_account_merged ( reserve_sig)) { struct TALER_AUDITORDB_BadSigLosses bsl = { - .row_id = rowid, + .problem_row_id = rowid, .operation = "account-merge", .loss = *purse_fee, .operation_specific_pub = reserve_pub->eddsa_pub @@ -1217,11 +1255,11 @@ handle_account_merged ( qs = TALER_ARL_adb->insert_bad_sig_losses ( TALER_ARL_adb->cls, &bsl); - if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling! + rc->qs = qs; + return GNUNET_SYSERR; } TALER_ARL_amount_add (&TALER_ARL_USE_AB (reserves_total_bad_sig_loss), &TALER_ARL_USE_AB (reserves_total_bad_sig_loss), @@ -1345,7 +1383,8 @@ verify_reserve_balance (void *cls, if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling! + rc->qs = qs; + return GNUNET_SYSERR; } /* Continue with a reserve balance of zero */ GNUNET_assert (GNUNET_OK == @@ -1364,9 +1403,10 @@ verify_reserve_balance (void *cls, in its database. This can only be done when we are doing an internal audit, as otherwise the balance of the 'reserves' table is not replicated at the auditor. */ - struct TALER_EXCHANGEDB_Reserve reserve; + struct TALER_EXCHANGEDB_Reserve reserve = { + .pub = rs->reserve_pub + }; - reserve.pub = rs->reserve_pub; qs = TALER_ARL_edb->reserves_get (TALER_ARL_edb->cls, &reserve); if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) @@ -1390,7 +1430,8 @@ verify_reserve_balance (void *cls, if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling + rc->qs = qs; + return GNUNET_SYSERR; } if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) { @@ -1405,7 +1446,6 @@ verify_reserve_balance (void *cls, if (0 != TALER_amount_cmp (&rs->curr_balance.reserve_balance, &reserve.balance)) { - struct TALER_Amount delta; if (0 < TALER_amount_cmp (&rs->curr_balance.reserve_balance, @@ -1450,7 +1490,8 @@ verify_reserve_balance (void *cls, if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling + rc->qs = qs; + return GNUNET_SYSERR; } { @@ -1469,7 +1510,8 @@ verify_reserve_balance (void *cls, if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling + rc->qs = qs; + return GNUNET_SYSERR; } } } @@ -1485,11 +1527,11 @@ verify_reserve_balance (void *cls, /* Reserve is expired */ struct TALER_Amount cfee; - if ((NULL != rs->sender_account) && - (GNUNET_OK == - get_closing_fee (rs->sender_account, - rs->a_expiration_date, - &cfee))) + if ( (NULL != rs->sender_account) && + (GNUNET_OK == + get_closing_fee (rs->sender_account, + rs->a_expiration_date, + &cfee)) ) { /* We got the closing fee */ if (1 == TALER_amount_cmp (&nbalance, @@ -1497,7 +1539,9 @@ verify_reserve_balance (void *cls, { struct TALER_AUDITORDB_ReserveNotClosedInconsistency rnci = { .reserve_pub = rs->reserve_pub, - .expiration_time = rs->a_expiration_date.abs_time + .expiration_time = rs->a_expiration_date.abs_time, + .balance = nbalance, + .diagnostic = rs->sender_account }; /* remaining balance (according to us) exceeds closing fee */ @@ -1509,18 +1553,18 @@ verify_reserve_balance (void *cls, qs = TALER_ARL_adb->insert_reserve_not_closed_inconsistency ( TALER_ARL_adb->cls, &rnci); - if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling + rc->qs = qs; + return GNUNET_SYSERR; } } } else { /* We failed to determine the closing fee, complain! */ - // TODO: fix correctly and not just comment out + // FIXME: fix correctly and not just comment out // nbalance is set to invalid and there is never a check happening when working further with nbalance, // why so and why adding those balances here? or what's the usecase of setting nbalance to zero? /* @@ -1540,7 +1584,8 @@ verify_reserve_balance (void *cls, if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - // FIXME: error handling + rc->qs = qs; + return GNUNET_SYSERR; } } } @@ -1592,6 +1637,8 @@ verify_reserve_balance (void *cls, &rs->total_out, /* what we needed */ 0 /* specific profit/loss does not apply to the total summary */ ); + if (global_qs < 0) + return GNUNET_SYSERR; /* We unexpectedly went negative, so a sane value to continue from would be zero. */ GNUNET_assert (GNUNET_OK == @@ -1664,6 +1711,22 @@ verify_reserve_balance (void *cls, } +#define CHECK_DB() do { \ + if (qs < 0) { \ + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); \ + return qs; \ + } \ + if (global_qs < 0) { \ + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == global_qs); \ + return global_qs; \ + } \ + if (rc.qs < 0) { \ + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == rc.qs); \ + return rc.qs; \ + } \ +} while (0) + + /** * Analyze reserves for being well-formed. * @@ -1673,15 +1736,16 @@ verify_reserve_balance (void *cls, static enum GNUNET_DB_QueryStatus analyze_reserves (void *cls) { - struct ReserveContext rc; - enum GNUNET_DB_QueryStatus qsx; + struct ReserveContext rc = { + .qs = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT + }; enum GNUNET_DB_QueryStatus qs; - enum GNUNET_DB_QueryStatus qsp; (void) cls; + global_qs = GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Analyzing reserves\n"); - qsp = TALER_ARL_adb->get_auditor_progress ( + qs = TALER_ARL_adb->get_auditor_progress ( TALER_ARL_adb->cls, TALER_ARL_GET_PP (reserves_reserve_in_serial_id), TALER_ARL_GET_PP (reserves_reserve_out_serial_id), @@ -1692,12 +1756,12 @@ analyze_reserves (void *cls) TALER_ARL_GET_PP (reserves_account_merges_serial_id), TALER_ARL_GET_PP (reserves_history_requests_serial_id), NULL); - if (0 > qsp) + if (0 > qs) { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsp); - return qsp; + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; } - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qsp) + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) { GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "First analysis using this auditor, starting audit from scratch\n"); @@ -1723,8 +1787,7 @@ analyze_reserves (void *cls) (unsigned long long) TALER_ARL_USE_PP ( reserves_history_requests_serial_id)); } - rc.qs = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; - qsx = TALER_ARL_adb->get_balance ( + qs = TALER_ARL_adb->get_balance ( TALER_ARL_adb->cls, TALER_ARL_GET_AB (reserves_reserve_total_balance), TALER_ARL_GET_AB (reserves_reserve_loss), @@ -1737,179 +1800,162 @@ analyze_reserves (void *cls) TALER_ARL_GET_AB (total_balance_reserve_not_closed), TALER_ARL_GET_AB (reserves_total_arithmetic_delta_plus), TALER_ARL_GET_AB (reserves_total_arithmetic_delta_minus), + TALER_ARL_GET_AB (total_balance_summary_delta_plus), TALER_ARL_GET_AB (total_balance_summary_delta_minus), NULL); - if (qsx < 0) + if (qs < 0) { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsx); - return qsx; + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; } rc.reserves = GNUNET_CONTAINER_multihashmap_create (512, GNUNET_NO); rc.revoked = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_NO); + qs = TALER_ARL_edb->select_reserves_in_above_serial_id ( TALER_ARL_edb->cls, TALER_ARL_USE_PP (reserves_reserve_in_serial_id), &handle_reserve_in, &rc); - if (qs < 0) - { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - return qs; - } + CHECK_DB (); qs = TALER_ARL_edb->select_withdrawals_above_serial_id ( TALER_ARL_edb->cls, TALER_ARL_USE_PP (reserves_reserve_out_serial_id), &handle_reserve_out, &rc); - if (qs < 0) - { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - return qs; - } + CHECK_DB (); qs = TALER_ARL_edb->select_recoup_above_serial_id ( TALER_ARL_edb->cls, TALER_ARL_USE_PP (reserves_reserve_recoup_serial_id), &handle_recoup_by_reserve, &rc); - if (qs < 0) + if ( (qs < 0) || + (rc.qs < 0) || + (global_qs < 0) ) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); return qs; } + qs = TALER_ARL_edb->select_reserve_open_above_serial_id ( TALER_ARL_edb->cls, TALER_ARL_USE_PP (reserves_reserve_open_serial_id), &handle_reserve_open, &rc); - if (qs < 0) - { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - return qs; - } + CHECK_DB (); qs = TALER_ARL_edb->select_reserve_closed_above_serial_id ( TALER_ARL_edb->cls, TALER_ARL_USE_PP (reserves_reserve_close_serial_id), &handle_reserve_closed, &rc); - if (qs < 0) - { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - return qs; - } + CHECK_DB (); /* process purse_decisions (to credit reserve) */ - if (0 > - (qs = TALER_ARL_edb->select_purse_decisions_above_serial_id ( - TALER_ARL_edb->cls, - TALER_ARL_USE_PP (reserves_purse_decisions_serial_id), - false, /* only go for merged purses! */ - &purse_decision_cb, - &rc))) - { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - return qs; - } - if (0 > rc.qs) - return rc.qs; + qs = TALER_ARL_edb->select_purse_decisions_above_serial_id ( + TALER_ARL_edb->cls, + TALER_ARL_USE_PP (reserves_purse_decisions_serial_id), + false, /* only go for merged purses! */ + &purse_decision_cb, + &rc); + CHECK_DB (); /* Charge purse fee! */ + qs = TALER_ARL_edb->select_account_merges_above_serial_id ( TALER_ARL_edb->cls, TALER_ARL_USE_PP (reserves_account_merges_serial_id), &handle_account_merged, &rc); - if (qs < 0) - { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - return qs; - } + CHECK_DB (); GNUNET_CONTAINER_multihashmap_iterate (rc.reserves, &verify_reserve_balance, &rc); + CHECK_DB (); GNUNET_break (0 == GNUNET_CONTAINER_multihashmap_size (rc.reserves)); GNUNET_CONTAINER_multihashmap_destroy (rc.reserves); GNUNET_CONTAINER_multihashmap_destroy (rc.revoked); - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != rc.qs) - return qs; - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qsx) - { - qs = TALER_ARL_adb->insert_balance ( - TALER_ARL_adb->cls, - TALER_ARL_SET_AB (reserves_reserve_total_balance), - TALER_ARL_SET_AB (reserves_reserve_loss), - TALER_ARL_SET_AB (reserves_withdraw_fee_revenue), - TALER_ARL_SET_AB (reserves_close_fee_revenue), - TALER_ARL_SET_AB (reserves_purse_fee_revenue), - TALER_ARL_SET_AB (reserves_open_fee_revenue), - TALER_ARL_SET_AB (reserves_history_fee_revenue), - TALER_ARL_SET_AB (reserves_total_bad_sig_loss), - TALER_ARL_SET_AB (total_balance_reserve_not_closed), - TALER_ARL_SET_AB (reserves_total_arithmetic_delta_plus), - TALER_ARL_SET_AB (reserves_total_arithmetic_delta_minus), - TALER_ARL_SET_AB (total_balance_summary_delta_minus), - NULL); - } - else - { - GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qsx); - qs = TALER_ARL_adb->update_balance ( - TALER_ARL_adb->cls, - TALER_ARL_SET_AB (reserves_reserve_total_balance), - TALER_ARL_SET_AB (reserves_reserve_loss), - TALER_ARL_SET_AB (reserves_withdraw_fee_revenue), - TALER_ARL_SET_AB (reserves_close_fee_revenue), - TALER_ARL_SET_AB (reserves_purse_fee_revenue), - TALER_ARL_SET_AB (reserves_open_fee_revenue), - TALER_ARL_SET_AB (reserves_history_fee_revenue), - TALER_ARL_SET_AB (reserves_total_bad_sig_loss), - TALER_ARL_SET_AB (total_balance_reserve_not_closed), - TALER_ARL_SET_AB (reserves_total_arithmetic_delta_plus), - TALER_ARL_SET_AB (reserves_total_arithmetic_delta_minus), - TALER_ARL_SET_AB (total_balance_summary_delta_minus), - NULL); - } - if (0 >= qs) + + qs = TALER_ARL_adb->insert_balance ( + TALER_ARL_adb->cls, + TALER_ARL_SET_AB (reserves_reserve_total_balance), + TALER_ARL_SET_AB (reserves_reserve_loss), + TALER_ARL_SET_AB (reserves_withdraw_fee_revenue), + TALER_ARL_SET_AB (reserves_close_fee_revenue), + TALER_ARL_SET_AB (reserves_purse_fee_revenue), + TALER_ARL_SET_AB (reserves_open_fee_revenue), + TALER_ARL_SET_AB (reserves_history_fee_revenue), + TALER_ARL_SET_AB (reserves_total_bad_sig_loss), + TALER_ARL_SET_AB (total_balance_reserve_not_closed), + TALER_ARL_SET_AB (reserves_total_arithmetic_delta_plus), + TALER_ARL_SET_AB (reserves_total_arithmetic_delta_minus), + TALER_ARL_SET_AB (total_balance_summary_delta_plus), + TALER_ARL_SET_AB (total_balance_summary_delta_minus), + NULL); + if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); return qs; } - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qsp) + + qs = TALER_ARL_adb->update_balance ( + TALER_ARL_adb->cls, + TALER_ARL_SET_AB (reserves_reserve_total_balance), + TALER_ARL_SET_AB (reserves_reserve_loss), + TALER_ARL_SET_AB (reserves_withdraw_fee_revenue), + TALER_ARL_SET_AB (reserves_close_fee_revenue), + TALER_ARL_SET_AB (reserves_purse_fee_revenue), + TALER_ARL_SET_AB (reserves_open_fee_revenue), + TALER_ARL_SET_AB (reserves_history_fee_revenue), + TALER_ARL_SET_AB (reserves_total_bad_sig_loss), + TALER_ARL_SET_AB (total_balance_reserve_not_closed), + TALER_ARL_SET_AB (reserves_total_arithmetic_delta_plus), + TALER_ARL_SET_AB (reserves_total_arithmetic_delta_minus), + TALER_ARL_SET_AB (total_balance_summary_delta_plus), + TALER_ARL_SET_AB (total_balance_summary_delta_minus), + NULL); + if (0 > qs) { - qs = TALER_ARL_adb->insert_auditor_progress ( - TALER_ARL_adb->cls, - TALER_ARL_SET_PP (reserves_reserve_in_serial_id), - TALER_ARL_SET_PP (reserves_reserve_out_serial_id), - TALER_ARL_SET_PP (reserves_reserve_recoup_serial_id), - TALER_ARL_SET_PP (reserves_reserve_open_serial_id), - TALER_ARL_SET_PP (reserves_reserve_close_serial_id), - TALER_ARL_SET_PP (reserves_purse_decisions_serial_id), - TALER_ARL_SET_PP (reserves_account_merges_serial_id), - TALER_ARL_SET_PP (reserves_history_requests_serial_id), - NULL); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; } - else + + qs = TALER_ARL_adb->insert_auditor_progress ( + TALER_ARL_adb->cls, + TALER_ARL_SET_PP (reserves_reserve_in_serial_id), + TALER_ARL_SET_PP (reserves_reserve_out_serial_id), + TALER_ARL_SET_PP (reserves_reserve_recoup_serial_id), + TALER_ARL_SET_PP (reserves_reserve_open_serial_id), + TALER_ARL_SET_PP (reserves_reserve_close_serial_id), + TALER_ARL_SET_PP (reserves_purse_decisions_serial_id), + TALER_ARL_SET_PP (reserves_account_merges_serial_id), + TALER_ARL_SET_PP (reserves_history_requests_serial_id), + NULL); + if (0 > qs) { - GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qsp); - qs = TALER_ARL_adb->update_auditor_progress ( - TALER_ARL_adb->cls, - TALER_ARL_SET_PP (reserves_reserve_in_serial_id), - TALER_ARL_SET_PP (reserves_reserve_out_serial_id), - TALER_ARL_SET_PP (reserves_reserve_recoup_serial_id), - TALER_ARL_SET_PP (reserves_reserve_open_serial_id), - TALER_ARL_SET_PP (reserves_reserve_close_serial_id), - TALER_ARL_SET_PP (reserves_purse_decisions_serial_id), - TALER_ARL_SET_PP (reserves_account_merges_serial_id), - TALER_ARL_SET_PP (reserves_history_requests_serial_id), - NULL); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Failed to update auditor DB, not recording progress\n"); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; } - if (0 >= qs) + qs = TALER_ARL_adb->update_auditor_progress ( + TALER_ARL_adb->cls, + TALER_ARL_SET_PP (reserves_reserve_in_serial_id), + TALER_ARL_SET_PP (reserves_reserve_out_serial_id), + TALER_ARL_SET_PP (reserves_reserve_recoup_serial_id), + TALER_ARL_SET_PP (reserves_reserve_open_serial_id), + TALER_ARL_SET_PP (reserves_reserve_close_serial_id), + TALER_ARL_SET_PP (reserves_purse_decisions_serial_id), + TALER_ARL_SET_PP (reserves_account_merges_serial_id), + TALER_ARL_SET_PP (reserves_history_requests_serial_id), + NULL); + if (0 > qs) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Failed to update auditor DB, not recording progress\n"); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); return qs; } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Concluded reserve audit step at %llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu\n", (unsigned long long) TALER_ARL_USE_PP ( @@ -1932,6 +1978,9 @@ analyze_reserves (void *cls) } +#undef CHECK_DB + + /** * Function called on events received from Postgres. * @@ -1996,10 +2045,8 @@ run (void *cls, (void) cfgfile; cfg = c; - GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Launching reserves auditor\n"); if (GNUNET_OK != @@ -2081,10 +2128,6 @@ main (int argc, not do this, the linker may "optimize" libtalerutil away and skip #TALER_OS_init(), which we do need */ (void) TALER_project_data_default (); - if (GNUNET_OK != - GNUNET_STRINGS_get_utf8_args (argc, argv, - &argc, &argv)) - return EXIT_INVALIDARGUMENT; ret = GNUNET_PROGRAM_run ( argc, argv, @@ -2093,7 +2136,6 @@ main (int argc, options, &run, NULL); - GNUNET_free_nz ((void *) argv); if (GNUNET_SYSERR == ret) return EXIT_INVALIDARGUMENT; if (GNUNET_NO == ret) diff --git a/src/auditor/taler-helper-auditor-transfer.c b/src/auditor/taler-helper-auditor-transfer.c new file mode 100644 index 000000000..3ebc04a4e --- /dev/null +++ b/src/auditor/taler-helper-auditor-transfer.c @@ -0,0 +1,556 @@ +/* + This file is part of TALER + Copyright (C) 2017-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 auditor/taler-helper-auditor-transfer.c + * @brief audits that deposits past due date are + * aggregated and have a matching wire transfer + * database. + * @author Christian Grothoff + */ +#include "platform.h" +#include <gnunet/gnunet_util_lib.h> +#include <gnunet/gnunet_curl_lib.h> +#include "taler_auditordb_plugin.h" +#include "taler_exchangedb_lib.h" +#include "taler_json_lib.h" +#include "taler_signatures.h" +#include "report-lib.h" +#include "taler_dbevents.h" + + +/** + * Run in test mode. Exit when idle instead of + * going to sleep and waiting for more work. + */ +static int test_mode; + +/** + * Return value from main(). + */ +static int global_ret; + +/** + * Last reserve_out / wire_out serial IDs seen. + */ +static TALER_ARL_DEF_PP (wire_batch_deposit_id); +static TALER_ARL_DEF_PP (wire_aggregation_id); + +/** + * Total amount which the exchange did not transfer in time. + */ +static TALER_ARL_DEF_AB (total_amount_lag); + +/** + * Should we run checks that only work for exchange-internal audits? + */ +static int internal_checks; + +/** + * Database event handler to wake us up again. + */ +static struct GNUNET_DB_EventHandler *eh; + +/** + * The auditors's configuration. + */ +static const struct GNUNET_CONFIGURATION_Handle *cfg; + + +/** + * Task run on shutdown. + * + * @param cls NULL + */ +static void +do_shutdown (void *cls) +{ + (void) cls; + if (NULL != eh) + { + TALER_ARL_adb->event_listen_cancel (eh); + eh = NULL; + } + TALER_ARL_done (); + TALER_EXCHANGEDB_unload_accounts (); + TALER_ARL_cfg = NULL; +} + + +/** + * Closure for import_wire_missing_cb(). + */ +struct ImportMissingWireContext +{ + /** + * Set to maximum row ID encountered. + */ + uint64_t max_batch_deposit_uuid; + + /** + * Set to database errors in callback. + */ + enum GNUNET_DB_QueryStatus err; +}; + + +/** + * Function called on deposits that need to be checked for their + * wire transfer. + * + * @param cls closure, points to a `struct ImportMissingWireContext` + * @param batch_deposit_serial_id serial of the entry in the batch deposits table + * @param total_amount value of the missing deposits, including fee + * @param wire_target_h_payto where should the funds be wired + * @param deadline what was the earliest requested wire transfer deadline + */ +static void +import_wire_missing_cb ( + void *cls, + uint64_t batch_deposit_serial_id, + const struct TALER_Amount *total_amount, + const struct TALER_PaytoHashP *wire_target_h_payto, + struct GNUNET_TIME_Timestamp deadline) +{ + struct ImportMissingWireContext *wc = cls; + enum GNUNET_DB_QueryStatus qs; + + if (wc->err < 0) + return; /* already failed */ + GNUNET_assert (batch_deposit_serial_id >= wc->max_batch_deposit_uuid); + wc->max_batch_deposit_uuid = batch_deposit_serial_id + 1; + qs = TALER_ARL_adb->insert_pending_deposit ( + TALER_ARL_adb->cls, + batch_deposit_serial_id, + wire_target_h_payto, + total_amount, + deadline); + if (qs < 0) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + wc->err = qs; + } + TALER_ARL_amount_add (&TALER_ARL_USE_AB (total_amount_lag), + &TALER_ARL_USE_AB (total_amount_lag), + total_amount); +} + + +/** + * Checks for wire transfers that should have happened. + * + * @return transaction status + */ +static enum GNUNET_DB_QueryStatus +check_for_required_transfers (void) +{ + enum GNUNET_DB_QueryStatus qs; + struct ImportMissingWireContext wc = { + .max_batch_deposit_uuid = TALER_ARL_USE_PP (wire_batch_deposit_id), + .err = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT + }; + + qs = TALER_ARL_edb->select_batch_deposits_missing_wire ( + TALER_ARL_edb->cls, + TALER_ARL_USE_PP (wire_batch_deposit_id), + &import_wire_missing_cb, + &wc); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; + } + if (0 > wc.err) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == wc.err); + return wc.err; + } + TALER_ARL_USE_PP (wire_batch_deposit_id) = wc.max_batch_deposit_uuid; + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; +} + + +/** + * Closure for #clear_finished_transfer_cb(). + */ +struct AggregationContext +{ + /** + * Set to maximum row ID encountered. + */ + uint64_t max_aggregation_serial; + + /** + * Set to database errors in callback. + */ + enum GNUNET_DB_QueryStatus err; +}; + + +/** + * 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 + */ +static void +clear_finished_transfer_cb ( + void *cls, + const struct TALER_Amount *amount, + uint64_t tracking_serial_id, + uint64_t batch_deposit_serial_id) +{ + struct AggregationContext *ac = cls; + enum GNUNET_DB_QueryStatus qs; + + if (0 > ac->err) + return; /* already failed */ + GNUNET_assert (ac->max_aggregation_serial <= tracking_serial_id); + ac->max_aggregation_serial = tracking_serial_id + 1; + qs = TALER_ARL_adb->delete_pending_deposit ( + TALER_ARL_adb->cls, + batch_deposit_serial_id); + if (0 == qs) + { + /* Aggregated something twice or other error, report! */ + GNUNET_break (0); + // FIXME: report more nicely! + return; + } + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + ac->err = qs; + return; + } + TALER_ARL_amount_subtract (&TALER_ARL_USE_AB (total_amount_lag), + &TALER_ARL_USE_AB (total_amount_lag), + amount); +} + + +/** + * Checks that all wire transfers that should have happened + * (based on deposits) have indeed happened. + * + * @return transaction status + */ +static enum GNUNET_DB_QueryStatus +check_for_completed_transfers (void) +{ + struct AggregationContext ac = { + .max_aggregation_serial = TALER_ARL_USE_PP (wire_aggregation_id), + .err = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT + }; + enum GNUNET_DB_QueryStatus qs; + + qs = TALER_ARL_edb->select_aggregations_above_serial ( + TALER_ARL_edb->cls, + TALER_ARL_USE_PP (wire_aggregation_id), + &clear_finished_transfer_cb, + &ac); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; + } + if (0 > ac.err) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == ac.err); + return ac.err; + } + TALER_ARL_USE_PP (wire_aggregation_id) = ac.max_aggregation_serial; + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; +} + + +/** + * Start the database transactions and begin the audit. + * + * @return transaction status + */ +static enum GNUNET_DB_QueryStatus +begin_transaction (void) +{ + enum GNUNET_DB_QueryStatus qs; + + if (GNUNET_SYSERR == + TALER_ARL_edb->preflight (TALER_ARL_edb->cls)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to initialize exchange database connection.\n"); + return GNUNET_DB_STATUS_HARD_ERROR; + } + if (GNUNET_SYSERR == + TALER_ARL_adb->preflight (TALER_ARL_adb->cls)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to initialize auditor database session.\n"); + return GNUNET_DB_STATUS_HARD_ERROR; + } + if (GNUNET_OK != + TALER_ARL_adb->start (TALER_ARL_adb->cls)) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + if (GNUNET_OK != + TALER_ARL_edb->start_read_only (TALER_ARL_edb->cls, + "transfer auditor")) + { + GNUNET_break (0); + TALER_ARL_adb->rollback (TALER_ARL_adb->cls); + return GNUNET_DB_STATUS_HARD_ERROR; + } + qs = TALER_ARL_adb->get_auditor_progress ( + TALER_ARL_adb->cls, + TALER_ARL_GET_PP (wire_batch_deposit_id), + TALER_ARL_GET_PP (wire_aggregation_id), + NULL); + if (0 > qs) + goto handle_db_error; + + qs = TALER_ARL_adb->get_balance ( + TALER_ARL_adb->cls, + TALER_ARL_GET_AB (total_amount_lag), + NULL); + if (0 > qs) + goto handle_db_error; + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + { + GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, + "First analysis of with transfer auditor, starting audit from scratch\n"); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Resuming transfer audit at %llu / %llu\n", + (unsigned long long) TALER_ARL_USE_PP (wire_batch_deposit_id), + (unsigned long long) TALER_ARL_USE_PP (wire_aggregation_id)); + } + + qs = check_for_required_transfers (); + if (0 > qs) + goto handle_db_error; + qs = check_for_completed_transfers (); + if (0 > qs) + goto handle_db_error; + + qs = TALER_ARL_adb->update_auditor_progress ( + TALER_ARL_adb->cls, + TALER_ARL_SET_PP (wire_batch_deposit_id), + TALER_ARL_SET_PP (wire_aggregation_id), + NULL); + if (0 > qs) + goto handle_db_error; + qs = TALER_ARL_adb->insert_auditor_progress ( + TALER_ARL_adb->cls, + TALER_ARL_SET_PP (wire_batch_deposit_id), + TALER_ARL_SET_PP (wire_aggregation_id), + NULL); + if (0 > qs) + goto handle_db_error; + qs = TALER_ARL_adb->update_balance ( + TALER_ARL_adb->cls, + TALER_ARL_SET_AB (total_amount_lag), + NULL); + if (0 > qs) + goto handle_db_error; + qs = TALER_ARL_adb->insert_balance ( + TALER_ARL_adb->cls, + TALER_ARL_SET_AB (total_amount_lag), + NULL); + if (0 > qs) + goto handle_db_error; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Concluded audit step at %llu/%llu\n", + (unsigned long long) TALER_ARL_USE_PP (wire_aggregation_id), + (unsigned long long) TALER_ARL_USE_PP (wire_batch_deposit_id)); + TALER_ARL_edb->rollback (TALER_ARL_edb->cls); + qs = TALER_ARL_adb->commit (TALER_ARL_adb->cls); + if (0 > qs) + goto handle_db_error; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Transaction concluded!\n"); + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; +handle_db_error: + TALER_ARL_adb->rollback (TALER_ARL_adb->cls); + TALER_ARL_edb->rollback (TALER_ARL_edb->cls); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; +} + + +/** + * Start auditor process. + */ +static void +start (void) +{ + enum GNUNET_DB_QueryStatus qs; + + for (unsigned int max_retries = 3; max_retries>0; max_retries--) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Trying again (%u attempts left)\n", + max_retries); + qs = begin_transaction (); + if (GNUNET_DB_STATUS_SOFT_ERROR != qs) + break; + } + if (0 > qs) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Audit failed\n"); + GNUNET_break (0); + global_ret = EXIT_FAILURE; + GNUNET_SCHEDULER_shutdown (); + return; + } +} + + +/** + * Function called on events received from Postgres. + * + * @param cls closure, NULL + * @param extra additional event data provided + * @param extra_size number of bytes in @a extra + */ +static void +db_notify (void *cls, + const void *extra, + size_t extra_size) +{ + (void) cls; + (void) extra; + (void) extra_size; + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Received notification to wake transfer helper\n"); + start (); +} + + +/** + * Main function that will be run. + * + * @param cls closure + * @param args remaining command-line arguments + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param c configuration + */ +static void +run (void *cls, + char *const *args, + const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *c) +{ + (void) cls; + (void) args; + (void) cfgfile; + cfg = c; + if (GNUNET_OK != + TALER_ARL_init (c)) + { + global_ret = EXIT_FAILURE; + return; + } + GNUNET_SCHEDULER_add_shutdown (&do_shutdown, + NULL); + if (GNUNET_OK != + TALER_EXCHANGEDB_load_accounts (TALER_ARL_cfg, + TALER_EXCHANGEDB_ALO_DEBIT + | TALER_EXCHANGEDB_ALO_CREDIT + | TALER_EXCHANGEDB_ALO_AUTHDATA)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "No bank accounts configured\n"); + global_ret = EXIT_NOTCONFIGURED; + GNUNET_SCHEDULER_shutdown (); + return; + } + if (0 == test_mode) + { + // FIXME: use different event type in the future! + struct GNUNET_DB_EventHeaderP es = { + .size = htons (sizeof (es)), + .type = htons (TALER_DBEVENT_EXCHANGE_AUDITOR_WAKE_HELPER_WIRE) + }; + + eh = TALER_ARL_adb->event_listen (TALER_ARL_adb->cls, + &es, + GNUNET_TIME_UNIT_FOREVER_REL, + &db_notify, + NULL); + GNUNET_assert (NULL != eh); + } + start (); +} + + +/** + * The main function of the wire auditing tool. Checks that + * the exchange's records of wire transfers match that of + * the wire gateway. + * + * @param argc number of arguments from the command line + * @param argv command line arguments + * @return 0 ok, 1 on error + */ +int +main (int argc, + char *const *argv) +{ + const struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_option_flag ('i', + "internal", + "perform checks only applicable for exchange-internal audits", + &internal_checks), + GNUNET_GETOPT_option_flag ('t', + "test", + "run in test mode and exit when idle", + &test_mode), + GNUNET_GETOPT_option_timetravel ('T', + "timetravel"), + GNUNET_GETOPT_OPTION_END + }; + enum GNUNET_GenericReturnValue ret; + + /* force linker to link against libtalerutil; if we do + not do this, the linker may "optimize" libtalerutil + away and skip #TALER_OS_init(), which we do need */ + (void) TALER_project_data_default (); + ret = GNUNET_PROGRAM_run ( + argc, + argv, + "taler-helper-auditor-transfer", + gettext_noop ( + "Audit exchange database for consistency of transfers with respect to deposit deadlines"), + options, + &run, + NULL); + if (GNUNET_SYSERR == ret) + return EXIT_INVALIDARGUMENT; + if (GNUNET_NO == ret) + return EXIT_SUCCESS; + return global_ret; +} + + +/* end of taler-helper-auditor-transfer.c */ diff --git a/src/auditor/taler-helper-auditor-wire-credit.c b/src/auditor/taler-helper-auditor-wire-credit.c index bf6856743..c37636e42 100644 --- a/src/auditor/taler-helper-auditor-wire-credit.c +++ b/src/auditor/taler-helper-auditor-wire-credit.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2017-2023 Taler Systems SA + Copyright (C) 2017-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 @@ -41,6 +41,12 @@ #define GRACE_PERIOD GNUNET_TIME_UNIT_HOURS /** + * Maximum number of wire transfers we process per + * (database) transaction. + */ +#define MAX_PER_TRANSACTION 1024 + +/** * How much do we allow the bank and the exchange to disagree about * timestamps? Should be sufficiently large to avoid bogus reports from deltas * created by imperfect clock synchronization and network delay. @@ -105,10 +111,6 @@ struct WireAccount */ char *label_wire_off_in; - /** - * Return value when we got this account's progress point. - */ - enum GNUNET_DB_QueryStatus qsx; }; @@ -140,11 +142,6 @@ static struct WireAccount *wa_head; static struct WireAccount *wa_tail; /** - * Last reserve_in seen. - */ -// static TALER_ARL_DEF_PP (wire_reserve_in_id); // FIXME: new! - -/** * Amount that is considered "tiny" */ static struct TALER_Amount tiny_amount; @@ -167,26 +164,11 @@ static TALER_ARL_DEF_AB (total_bad_amount_in_minus); static TALER_ARL_DEF_AB (total_misattribution_in); /** - * Total amount affected by wire format troubles. - */ -static TALER_ARL_DEF_AB (total_wire_format_amount); // FIXME - -/** * Total amount credited to exchange accounts. */ static TALER_ARL_DEF_AB (total_wire_in); /** - * True if #total_wire_in was initialized. - */ -static bool had_start_balance; - -/** - * True if #wire_reserve_in_id was initialized. - */ -static bool had_start_progress; - -/** * Amount of zero in our currency. */ static struct TALER_Amount zero; @@ -212,7 +194,9 @@ static int internal_checks; */ static int ignore_account_404; -// FIXME: comment +/** + * Database event handler to wake us up again. + */ static struct GNUNET_DB_EventHandler *eh; /** @@ -329,6 +313,15 @@ do_shutdown (void *cls) /** + * Start the database transactions and begin the audit. + * + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +begin_transaction (void); + + +/** * Commit the transaction, checkpointing our progress in the auditor DB. * * @param qs transaction status so far @@ -336,100 +329,82 @@ do_shutdown (void *cls) static void commit (enum GNUNET_DB_QueryStatus qs) { - if (qs >= 0) - { - if (had_start_balance) - { - qs = TALER_ARL_adb->update_balance ( - TALER_ARL_adb->cls, - TALER_ARL_SET_AB (total_wire_in), - TALER_ARL_SET_AB (total_bad_amount_in_plus), - TALER_ARL_SET_AB (total_bad_amount_in_minus), - TALER_ARL_SET_AB (total_misattribution_in), - TALER_ARL_SET_AB (total_wire_format_amount), - NULL); - } - else - { - qs = TALER_ARL_adb->insert_balance ( - TALER_ARL_adb->cls, - TALER_ARL_SET_AB (total_wire_in), - TALER_ARL_SET_AB (total_bad_amount_in_plus), - TALER_ARL_SET_AB (total_bad_amount_in_minus), - TALER_ARL_SET_AB (total_misattribution_in), - TALER_ARL_SET_AB (total_wire_format_amount), - NULL); - } - } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Transaction logic ended with status %d\n", + qs); + TALER_ARL_edb->rollback (TALER_ARL_edb->cls); + if (qs < 0) + goto handle_db_error; + qs = TALER_ARL_adb->update_balance ( + TALER_ARL_adb->cls, + TALER_ARL_SET_AB (total_wire_in), + TALER_ARL_SET_AB (total_bad_amount_in_plus), + TALER_ARL_SET_AB (total_bad_amount_in_minus), + TALER_ARL_SET_AB (total_misattribution_in), + NULL); if (0 > qs) - { - if (GNUNET_DB_STATUS_SOFT_ERROR == qs) - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Serialization issue, not recording progress\n"); - else - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Hard error, not recording progress\n"); - TALER_ARL_adb->rollback (TALER_ARL_adb->cls); - TALER_ARL_edb->rollback (TALER_ARL_edb->cls); - return; - } + goto handle_db_error; + qs = TALER_ARL_adb->insert_balance ( + TALER_ARL_adb->cls, + TALER_ARL_SET_AB (total_wire_in), + TALER_ARL_SET_AB (total_bad_amount_in_plus), + TALER_ARL_SET_AB (total_bad_amount_in_minus), + TALER_ARL_SET_AB (total_misattribution_in), + NULL); + if (0 > qs) + goto handle_db_error; for (struct WireAccount *wa = wa_head; NULL != wa; wa = wa->next) { - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == wa->qsx && - had_start_progress) - qs = TALER_ARL_adb->update_auditor_progress ( - TALER_ARL_adb->cls, - wa->label_reserve_in_serial_id, - wa->last_reserve_in_serial_id, - wa->label_wire_off_in, - wa->wire_off_in, - NULL); - else - qs = TALER_ARL_adb->insert_auditor_progress ( - TALER_ARL_adb->cls, - wa->label_reserve_in_serial_id, - wa->last_reserve_in_serial_id, - wa->label_wire_off_in, - wa->wire_off_in, - NULL); - if (0 >= qs) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Failed to update auditor DB, not recording progress\n"); - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - return; - } + qs = TALER_ARL_adb->update_auditor_progress ( + TALER_ARL_adb->cls, + wa->label_reserve_in_serial_id, + wa->last_reserve_in_serial_id, + wa->label_wire_off_in, + wa->wire_off_in, + NULL); + if (0 > qs) + goto handle_db_error; + qs = TALER_ARL_adb->insert_auditor_progress ( + TALER_ARL_adb->cls, + wa->label_reserve_in_serial_id, + wa->last_reserve_in_serial_id, + wa->label_wire_off_in, + wa->wire_off_in, + NULL); + if (0 > qs) + goto handle_db_error; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Transaction ends at %s=%llu for account `%s'\n", + wa->label_reserve_in_serial_id, + (unsigned long long) wa->last_reserve_in_serial_id, + wa->ai->section_name); } - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) + qs = TALER_ARL_adb->commit (TALER_ARL_adb->cls); + if (0 > qs) { - qs = TALER_ARL_edb->commit (TALER_ARL_edb->cls); - if (0 > qs) - { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Exchange DB commit failed, rolling back transaction\n"); - TALER_ARL_adb->rollback (TALER_ARL_adb->cls); - } - else - { - qs = TALER_ARL_adb->commit (TALER_ARL_adb->cls); - if (0 > qs) - { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Auditor DB commit failed!\n"); - } - } + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + goto handle_db_error; } - else + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Transaction concluded!\n"); + if (1 == test_mode) + GNUNET_SCHEDULER_shutdown (); + return; +handle_db_error: + TALER_ARL_adb->rollback (TALER_ARL_adb->cls); + for (unsigned int max_retries = 3; max_retries>0; max_retries--) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Processing failed, rolling back transaction\n"); - TALER_ARL_adb->rollback (TALER_ARL_adb->cls); - TALER_ARL_edb->rollback (TALER_ARL_edb->cls); + if (GNUNET_DB_STATUS_HARD_ERROR == qs) + break; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Serialization issue, trying again\n"); + qs = begin_transaction (); } + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Hard database error, terminating\n"); + GNUNET_SCHEDULER_shutdown (); } @@ -443,6 +418,8 @@ conclude_credit_history (void) { if (NULL != in_map) { + GNUNET_assert (0 == + GNUNET_CONTAINER_multihashmap_size (in_map)); GNUNET_CONTAINER_multihashmap_destroy (in_map); in_map = NULL; } @@ -475,7 +452,9 @@ reserve_in_cb (void *cls, struct WireAccount *wa = cls; struct ReserveInInfo *rii; size_t slen; + char *snp; + snp = TALER_payto_normalize (sender_account_details); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Analyzing exchange wire IN (%llu) at %s of %s with reserve_pub %s\n", (unsigned long long) rowid, @@ -485,7 +464,7 @@ reserve_in_cb (void *cls, TALER_ARL_amount_add (&TALER_ARL_USE_AB (total_wire_in), &TALER_ARL_USE_AB (total_wire_in), credit); - slen = strlen (sender_account_details) + 1; + slen = strlen (snp) + 1; rii = GNUNET_malloc (sizeof (struct ReserveInInfo) + slen); rii->rowid = rowid; rii->credit_details.type = TALER_BANK_CT_RESERVE; @@ -494,8 +473,9 @@ reserve_in_cb (void *cls, rii->credit_details.details.reserve.reserve_pub = *reserve_pub; rii->credit_details.debit_account_uri = (const char *) &rii[1]; GNUNET_memcpy (&rii[1], - sender_account_details, + snp, slen); + GNUNET_free (snp); GNUNET_CRYPTO_hash (&wire_reference, sizeof (uint64_t), &rii->row_off_hash); @@ -512,6 +492,8 @@ reserve_in_cb (void *cls, }; enum GNUNET_DB_QueryStatus qs; + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Duplicate wire offset\n"); qs = TALER_ARL_adb->insert_row_inconsistency ( TALER_ARL_adb->cls, &ri); @@ -546,7 +528,7 @@ complain_in_not_found (void *cls, struct ReserveInInfo *rii = value; enum GNUNET_DB_QueryStatus qs; struct TALER_AUDITORDB_ReserveInInconsistency riiDb = { - .row_id = rii->rowid, + .bank_row_id = rii->rowid, .diagnostic = "incoming wire transfer claimed by exchange not found", .account = (char *) wa->ai->section_name, .amount_exchange_expected = rii->credit_details.amount, @@ -556,6 +538,9 @@ complain_in_not_found (void *cls, }; (void) key; + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Incoming wire transfer #%llu claimed by exchange not found\n", + (unsigned long long) rii->rowid); GNUNET_assert (TALER_BANK_CT_RESERVE == rii->credit_details.type); qs = TALER_ARL_adb->insert_reserve_in_inconsistency ( @@ -633,7 +618,8 @@ analyze_credit ( GNUNET_assert (TALER_BANK_CT_RESERVE == credit_details->type); GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Analyzing bank CREDIT at %s of %s with Reserve-pub %s\n", + "Analyzing bank CREDIT #%llu at %s of %s with Reserve-pub %s\n", + (unsigned long long) credit_details->serial_id, GNUNET_TIME_timestamp2s (credit_details->execution_date), TALER_amount2s (&credit_details->amount), TALER_B2S (&credit_details->details.reserve.reserve_pub)); @@ -644,11 +630,12 @@ analyze_credit ( &key); if (NULL == rii) { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Failed to find wire transfer at `%s' in exchange database. Audit ends at this point in time.\n", + // FIXME: add to auditor DB and report missing! + // (and modify balances!) + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Failed to find wire transfer at `%s' in exchange database.\n", GNUNET_TIME_timestamp2s (credit_details->execution_date)); - process_credits (wa->next); - return false; /* not an error, just end of processing */ + return true; } /* Update offset */ @@ -660,7 +647,7 @@ analyze_credit ( struct TALER_AUDITORDB_ReserveInInconsistency riiDb = { .diagnostic = "wire subject does not match", .account = (char *) wa->ai->section_name, - .row_id = credit_details->serial_id, // FIXME: correct row? + .bank_row_id = credit_details->serial_id, .amount_exchange_expected = rii->credit_details.amount, .amount_wired = zero, .reserve_pub = rii->credit_details.details.reserve.reserve_pub, @@ -668,6 +655,8 @@ analyze_credit ( }; enum GNUNET_DB_QueryStatus qs; + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Reserve public key differs\n"); qs = TALER_ARL_adb->insert_reserve_in_inconsistency ( TALER_ARL_adb->cls, &riiDb); @@ -695,7 +684,7 @@ analyze_credit ( struct TALER_AUDITORDB_ReserveInInconsistency riiDb = { .diagnostic = "wire amount does not match", .account = (char *) wa->ai->section_name, - .row_id = credit_details->serial_id, // FIXME: correct row? + .bank_row_id = credit_details->serial_id, .amount_exchange_expected = rii->credit_details.amount, .amount_wired = credit_details->amount, .reserve_pub = rii->credit_details.details.reserve.reserve_pub, @@ -703,6 +692,8 @@ analyze_credit ( }; enum GNUNET_DB_QueryStatus qs; + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Wire transfer amount differs\n"); qs = TALER_ARL_adb->insert_reserve_in_inconsistency ( TALER_ARL_adb->cls, &riiDb); @@ -739,51 +730,67 @@ analyze_credit ( } } - if (0 != strcasecmp (credit_details->debit_account_uri, - rii->credit_details.debit_account_uri)) { - struct TALER_AUDITORDB_MisattributionInInconsistency mii = { - .reserve_pub = rii->credit_details.details.reserve.reserve_pub, - .amount = rii->credit_details.amount, - .bank_row = credit_details->serial_id - }; - enum GNUNET_DB_QueryStatus qs; + char *np; - qs = TALER_ARL_adb->insert_misattribution_in_inconsistency ( - TALER_ARL_adb->cls, - &mii); - if (qs <= 0) + np = TALER_payto_normalize (credit_details->debit_account_uri); + if (0 != strcasecmp (np, + rii->credit_details.debit_account_uri)) { - global_qs = qs; - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - return false; + struct TALER_AUDITORDB_MisattributionInInconsistency mii = { + .reserve_pub = rii->credit_details.details.reserve.reserve_pub, + .amount = rii->credit_details.amount, + .bank_row = credit_details->serial_id + }; + enum GNUNET_DB_QueryStatus qs; + + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Origin bank account differs\n"); + qs = TALER_ARL_adb->insert_misattribution_in_inconsistency ( + TALER_ARL_adb->cls, + &mii); + if (qs <= 0) + { + global_qs = qs; + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + GNUNET_free (np); + return false; + } + TALER_ARL_amount_add (&TALER_ARL_USE_AB (total_misattribution_in), + &TALER_ARL_USE_AB (total_misattribution_in), + &rii->credit_details.amount); } - TALER_ARL_amount_add (&TALER_ARL_USE_AB (total_misattribution_in), - &TALER_ARL_USE_AB (total_misattribution_in), - &rii->credit_details.amount); + GNUNET_free (np); } if (GNUNET_TIME_timestamp_cmp (credit_details->execution_date, !=, rii->credit_details.execution_date)) { struct TALER_AUDITORDB_RowMinorInconsistencies rmi = { - .row_id = rii->rowid, + .problem_row = rii->rowid, .diagnostic = "execution date mismatch", .row_table = "reserves_in" }; enum GNUNET_DB_QueryStatus qs; + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Execution date differs\n"); qs = TALER_ARL_adb->insert_row_minor_inconsistencies ( TALER_ARL_adb->cls, &rmi); - if (qs <= 0) + if (qs < 0) { + /* FIXME: this error handling sucks... */ global_qs = qs; GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); return false; } } + GNUNET_assert (GNUNET_OK == + free_rii (NULL, + &key, + rii)); return true; } @@ -813,7 +820,17 @@ history_credit_cb (void *cls, if (! analyze_credit (wa, cd)) - return; + { + if (global_qs < 0) + { + /* FIXME: this error handling sucks, + doesn't retry on SOFT errors, doesn't + set global_ret, etc. */ + GNUNET_SCHEDULER_shutdown (); + return; + } + break; + } } conclude_account (wa); return; @@ -831,7 +848,7 @@ history_credit_cb (void *cls, break; } GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error fetching credit history of account %s: %u/%s!\n", + "Error fetching credit history of account %s: %u (%s)\n", wa->ai->section_name, chr->http_status, TALER_ErrorCode_get_hint (chr->ec)); @@ -857,8 +874,8 @@ process_credits (void *cls) enum GNUNET_DB_QueryStatus qs; /* skip accounts where CREDIT is not enabled */ - while ((NULL != wa) && - (GNUNET_NO == wa->ai->credit_enabled)) + while ( (NULL != wa) && + (GNUNET_NO == wa->ai->credit_enabled) ) wa = wa->next; if (NULL == wa) { @@ -892,12 +909,10 @@ process_credits (void *cls) GNUNET_log (GNUNET_ERROR_TYPE_INFO, "pass `%s'\n", wa->ai->auth->details.basic.password); - // NOTE: handle the case where more than INT32_MAX transactions exist. - // (CG: used to be INT64_MAX, changed by MS to INT32_MAX, why? To be discussed with him!) wa->chh = TALER_BANK_credit_history (ctx, wa->ai->auth, wa->wire_off_in, - INT32_MAX, + MAX_PER_TRANSACTION, GNUNET_TIME_UNIT_ZERO, &history_credit_cb, wa); @@ -927,11 +942,6 @@ begin_credit_audit (void) } -/** - * Start the database transactions and begin the audit. - * - * @return transaction status code - */ static enum GNUNET_DB_QueryStatus begin_transaction (void) { @@ -958,10 +968,9 @@ begin_transaction (void) GNUNET_break (0); return GNUNET_DB_STATUS_HARD_ERROR; } - TALER_ARL_edb->preflight (TALER_ARL_edb->cls); if (GNUNET_OK != - TALER_ARL_edb->start (TALER_ARL_edb->cls, - "wire auditor")) + TALER_ARL_edb->start_read_only (TALER_ARL_edb->cls, + "wire credit auditor")) { GNUNET_break (0); return GNUNET_DB_STATUS_HARD_ERROR; @@ -972,7 +981,6 @@ begin_transaction (void) TALER_ARL_GET_AB (total_bad_amount_in_plus), TALER_ARL_GET_AB (total_bad_amount_in_minus), TALER_ARL_GET_AB (total_misattribution_in), - TALER_ARL_GET_AB (total_wire_format_amount), NULL); switch (qs) { @@ -983,10 +991,7 @@ begin_transaction (void) GNUNET_break (0); return qs; case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - had_start_balance = false; - break; case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - had_start_balance = true; break; } for (struct WireAccount *wa = wa_head; @@ -1001,20 +1006,26 @@ begin_transaction (void) "wire-%s-%s", wa->ai->section_name, "wire_off_in"); - wa->qsx = TALER_ARL_adb->get_auditor_progress ( + qs = TALER_ARL_adb->get_auditor_progress ( TALER_ARL_adb->cls, wa->label_reserve_in_serial_id, &wa->last_reserve_in_serial_id, wa->label_wire_off_in, &wa->wire_off_in, NULL); - if (0 > wa->qsx) + if (0 > qs) { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == wa->qsx); - return GNUNET_DB_STATUS_HARD_ERROR; + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; } wa->start_reserve_in_serial_id = wa->last_reserve_in_serial_id; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Starting from reserve_in at %s=%llu for account `%s'\n", + wa->label_reserve_in_serial_id, + (unsigned long long) wa->start_reserve_in_serial_id, + wa->ai->section_name); } + begin_credit_audit (); return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; } @@ -1111,6 +1122,9 @@ run (void *cls, "TINY_AMOUNT", &tiny_amount)) { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "auditor", + "TINY_AMOUNT"); global_ret = EXIT_NOTCONFIGURED; return; } @@ -1203,10 +1217,6 @@ main (int argc, not do this, the linker may "optimize" libtalerutil away and skip #TALER_OS_init(), which we do need */ (void) TALER_project_data_default (); - if (GNUNET_OK != - GNUNET_STRINGS_get_utf8_args (argc, argv, - &argc, &argv)) - return EXIT_INVALIDARGUMENT; ret = GNUNET_PROGRAM_run ( argc, argv, @@ -1216,7 +1226,6 @@ main (int argc, options, &run, NULL); - GNUNET_free_nz ((void *) argv); if (GNUNET_SYSERR == ret) return EXIT_INVALIDARGUMENT; if (GNUNET_NO == ret) diff --git a/src/auditor/taler-helper-auditor-wire-debit.c b/src/auditor/taler-helper-auditor-wire-debit.c index e6bb4d50e..e093fd851 100644 --- a/src/auditor/taler-helper-auditor-wire-debit.c +++ b/src/auditor/taler-helper-auditor-wire-debit.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2017-2023 Taler Systems SA + Copyright (C) 2017-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 @@ -21,9 +21,14 @@ * @author Özgür Kesim * * - We check that the outgoing wire transfers match those - * given in the 'wire_out' and 'reserve_closures' tables - * - Finally, we check that all wire transfers that should have been made, - * were actually made + * given in the 'wire_out' and 'reserve_closures' tables; + * any outgoing transfer MUST have a prior justification, + * so if one is missing we flag it (and never remove it). + * - We check that all wire transfers that should + * have been made, were actually made. If any were not made, + * we flag those, but may remove those flags if we later + * find that the wire transfers were made (wire transfers + * could be delayed due to AML/KYC or core-banking issues). */ #include "platform.h" #include <gnunet/gnunet_util_lib.h> @@ -38,19 +43,35 @@ /** - * How much time do we allow the aggregator to lag behind? If - * wire transfers should have been made more than #GRACE_PERIOD - * before, we issue warnings. + * Maximum number of wire transfers we process per + * (database) transaction. */ -#define GRACE_PERIOD GNUNET_TIME_UNIT_HOURS +#define MAX_PER_TRANSACTION 1024 /** * How much do we allow the bank and the exchange to disagree about * timestamps? Should be sufficiently large to avoid bogus reports from deltas * created by imperfect clock synchronization and network delay. */ -#define TIME_TOLERANCE GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, \ - 15) +#define TIME_TOLERANCE GNUNET_TIME_relative_multiply ( \ + GNUNET_TIME_UNIT_MINUTES, \ + 15) + + +/** + * How long do we try to long-poll for bank wire transfers? + */ +#define MAX_LONGPOLL_DELAY GNUNET_TIME_relative_multiply ( \ + GNUNET_TIME_UNIT_HOURS, \ + 1) + + +/** + * How long do we wait between polling for bank wire transfers at the minimum? + */ +#define MIN_LONGPOLL_DELAY GNUNET_TIME_relative_multiply ( \ + GNUNET_TIME_UNIT_MINUTES, \ + 5) /** @@ -86,6 +107,17 @@ struct WireAccount struct TALER_BANK_DebitHistoryHandle *dhh; /** + * Task to trigger @e dhh long-polling. + */ + struct GNUNET_SCHEDULER_Task *dhh_task; + + /** + * Time when we expect the current @e dhh long-poll + * to finish and we thus could begin another one. + */ + struct GNUNET_TIME_Absolute dhh_next; + + /** * Progress point for this account. */ uint64_t last_wire_out_serial_id; @@ -109,11 +141,6 @@ struct WireAccount * Label under which we store our wire_off_out. */ char *label_wire_off_out; - - /** - * Return value when we got this account's progress point. - */ - enum GNUNET_DB_QueryStatus qsx; }; @@ -183,17 +210,9 @@ static struct WireAccount *wa_head; static struct WireAccount *wa_tail; /** - * Query status for the incremental processing status in the auditordb. - * Return value from our call to the "get_wire_auditor_progress" function. - */ -static enum GNUNET_DB_QueryStatus qsx_gwap; - -/** * Last reserve_out / wire_out serial IDs seen. */ static TALER_ARL_DEF_PP (wire_reserve_close_id); -static TALER_ARL_DEF_PP (wire_batch_deposit_id); -static TALER_ARL_DEF_PP (wire_aggregation_id); /** * Amount that is considered "tiny" @@ -211,19 +230,15 @@ static TALER_ARL_DEF_AB (total_bad_amount_out_plus); static TALER_ARL_DEF_AB (total_bad_amount_out_minus); /** - * Total amount which the exchange did not transfer in time. - */ -static TALER_ARL_DEF_AB (total_amount_lag); - -/** * Total amount of reserve closures which the exchange did not transfer in time. */ static TALER_ARL_DEF_AB (total_closure_amount_lag); /** - * Total amount affected by wire format troubles. + * Total amount affected by duplicate wire transfer + * subjects. */ -static TALER_ARL_DEF_AB (total_wire_format_amount); +static TALER_ARL_DEF_AB (wire_debit_duplicate_transfer_subject_total); /** * Total amount debited to exchange accounts. @@ -236,16 +251,6 @@ static TALER_ARL_DEF_AB (total_wire_out); static TALER_ARL_DEF_AB (total_drained); /** - * True if #start_balance was initialized. - */ -static bool had_start_balance; - -/** - * True if #start_balance was initialized. - */ -static bool had_start_progress; - -/** * Amount of zero in our currency. */ static struct TALER_Amount zero; @@ -258,7 +263,7 @@ static struct GNUNET_CURL_Context *ctx; /** * Scheduler context for running the @e ctx. */ -static struct GNUNET_CURL_RescheduleContext *rc; +static struct GNUNET_CURL_RescheduleContext *rctx; /** * Should we run checks that only work for exchange-internal audits? @@ -388,6 +393,11 @@ do_shutdown (void *cls) } while (NULL != (wa = wa_head)) { + if (NULL != wa->dhh_task) + { + GNUNET_SCHEDULER_cancel (wa->dhh_task); + wa->dhh_task = NULL; + } if (NULL != wa->dhh) { TALER_BANK_debit_history_cancel (wa->dhh); @@ -405,10 +415,10 @@ do_shutdown (void *cls) GNUNET_CURL_fini (ctx); ctx = NULL; } - if (NULL != rc) + if (NULL != rctx) { - GNUNET_CURL_gnunet_rc_destroy (rc); - rc = NULL; + GNUNET_CURL_gnunet_rc_destroy (rctx); + rctx = NULL; } TALER_EXCHANGEDB_unload_accounts (); TALER_ARL_cfg = NULL; @@ -434,12 +444,13 @@ check_pending_rc (void *cls, (void) cls; (void) key; - TALER_ARL_amount_add (&TALER_ARL_USE_AB (total_closure_amount_lag), - &TALER_ARL_USE_AB (total_closure_amount_lag), - &rc->amount); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Missing wire transfer for closed reserve with balance %s\n", + TALER_amount2s (&rc->amount)); if (! TALER_amount_is_zero (&rc->amount)) { struct TALER_AUDITORDB_ClosureLags cl = { + .problem_row_id = rc->rowid, .account = rc->receiver_account, .amount = rc->amount, .deadline = rc->execution_date.abs_time, @@ -447,6 +458,8 @@ check_pending_rc (void *cls, }; enum GNUNET_DB_QueryStatus qs; + /* FIXME: where do we *undo* this if the wire transfer is + found later? */ qs = TALER_ARL_adb->insert_auditor_closure_lags ( TALER_ARL_adb->cls, &cl); @@ -456,10 +469,12 @@ check_pending_rc (void *cls, GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); return GNUNET_SYSERR; } + /* FIXME: where do we *undo* this if the wire transfer is + found later? */ + TALER_ARL_amount_add (&TALER_ARL_USE_AB (total_closure_amount_lag), + &TALER_ARL_USE_AB (total_closure_amount_lag), + &rc->amount); } - TALER_ARL_USE_PP (wire_reserve_close_id) - = GNUNET_MIN (TALER_ARL_USE_PP (wire_reserve_close_id), - rc->rowid); return GNUNET_OK; } @@ -493,582 +508,547 @@ hash_rc (const char *receiver_account, /** + * Start the database transactions and begin the audit. + * + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +begin_transaction (void); + + +/** * Commit the transaction, checkpointing our progress in the auditor DB. * * @param qs transaction status so far - * @return transaction status code */ static void commit (enum GNUNET_DB_QueryStatus qs) { - if (qs >= 0) - { - if (had_start_balance) - { - qs = TALER_ARL_adb->update_balance ( - TALER_ARL_adb->cls, - TALER_ARL_SET_AB (total_drained), - TALER_ARL_SET_AB (total_wire_out), - TALER_ARL_SET_AB (total_bad_amount_out_plus), - TALER_ARL_SET_AB (total_bad_amount_out_minus), - TALER_ARL_SET_AB (total_amount_lag), - TALER_ARL_SET_AB (total_closure_amount_lag), - TALER_ARL_SET_AB (total_wire_format_amount), - TALER_ARL_SET_AB (total_wire_out), - NULL); - } - else - { - qs = TALER_ARL_adb->insert_balance ( - TALER_ARL_adb->cls, - TALER_ARL_SET_AB (total_drained), - TALER_ARL_SET_AB (total_wire_out), - TALER_ARL_SET_AB (total_bad_amount_out_plus), - TALER_ARL_SET_AB (total_bad_amount_out_minus), - TALER_ARL_SET_AB (total_amount_lag), - TALER_ARL_SET_AB (total_closure_amount_lag), - TALER_ARL_SET_AB (total_wire_format_amount), - TALER_ARL_SET_AB (total_wire_out), - NULL); - } - } + GNUNET_CONTAINER_multihashmap_iterate (reserve_closures, + &check_pending_rc, + NULL); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Transaction logic ended with status %d\n", + qs); + TALER_ARL_edb->rollback (TALER_ARL_edb->cls); + qs = TALER_ARL_adb->update_balance ( + TALER_ARL_adb->cls, + TALER_ARL_SET_AB (total_drained), + TALER_ARL_SET_AB (total_wire_out), + TALER_ARL_SET_AB (total_bad_amount_out_plus), + TALER_ARL_SET_AB (total_bad_amount_out_minus), + TALER_ARL_SET_AB (total_closure_amount_lag), + TALER_ARL_SET_AB (wire_debit_duplicate_transfer_subject_total), + TALER_ARL_SET_AB (total_wire_out), + NULL); if (0 > qs) - { - if (GNUNET_DB_STATUS_SOFT_ERROR == qs) - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Serialization issue, not recording progress\n"); - else - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Hard error, not recording progress\n"); - TALER_ARL_adb->rollback (TALER_ARL_adb->cls); - TALER_ARL_edb->rollback (TALER_ARL_edb->cls); - return; - } + goto handle_db_error; + qs = TALER_ARL_adb->insert_balance ( + TALER_ARL_adb->cls, + TALER_ARL_SET_AB (total_drained), + TALER_ARL_SET_AB (total_wire_out), + TALER_ARL_SET_AB (total_bad_amount_out_plus), + TALER_ARL_SET_AB (total_bad_amount_out_minus), + TALER_ARL_SET_AB (total_closure_amount_lag), + TALER_ARL_SET_AB (wire_debit_duplicate_transfer_subject_total), + TALER_ARL_SET_AB (total_wire_out), + NULL); + if (0 > qs) + goto handle_db_error; for (struct WireAccount *wa = wa_head; NULL != wa; wa = wa->next) { - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == wa->qsx && - had_start_progress) - qs = TALER_ARL_adb->update_auditor_progress ( - TALER_ARL_adb->cls, - wa->label_wire_out_serial_id, - wa->last_wire_out_serial_id, - wa->label_wire_off_out, - wa->wire_off_out, - NULL); - else - qs = TALER_ARL_adb->insert_auditor_progress ( - TALER_ARL_adb->cls, - wa->label_wire_out_serial_id, - wa->last_wire_out_serial_id, - wa->label_wire_off_out, - wa->wire_off_out, - NULL); - if (0 >= qs) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Failed to update auditor DB, not recording progress\n"); - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - return; - } - } - GNUNET_CONTAINER_multihashmap_iterate (reserve_closures, - &check_pending_rc, - NULL); - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qsx_gwap && had_start_progress == - true) + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Transaction of account %s ends at %llu/%llu\n", + wa->ai->section_name, + (unsigned long long) wa->last_wire_out_serial_id, + (unsigned long long) wa->wire_off_out); qs = TALER_ARL_adb->update_auditor_progress ( TALER_ARL_adb->cls, - TALER_ARL_SET_PP (wire_reserve_close_id), - TALER_ARL_SET_PP (wire_batch_deposit_id), - TALER_ARL_SET_PP (wire_aggregation_id), + wa->label_wire_out_serial_id, + wa->last_wire_out_serial_id, + wa->label_wire_off_out, + wa->wire_off_out, NULL); - else + if (0 > qs) + goto handle_db_error; qs = TALER_ARL_adb->insert_auditor_progress ( TALER_ARL_adb->cls, - TALER_ARL_SET_PP (wire_reserve_close_id), - TALER_ARL_SET_PP (wire_batch_deposit_id), - TALER_ARL_SET_PP (wire_aggregation_id), + wa->label_wire_out_serial_id, + wa->last_wire_out_serial_id, + wa->label_wire_off_out, + wa->wire_off_out, NULL); - if (0 >= qs) - { + if (0 > qs) + goto handle_db_error; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Failed to update auditor DB, not recording progress\n"); - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - return; + "Transaction ends at %s=%llu for account `%s'\n", + wa->label_wire_out_serial_id, + (unsigned long long) wa->last_wire_out_serial_id, + wa->ai->section_name); } + qs = TALER_ARL_adb->update_auditor_progress ( + TALER_ARL_adb->cls, + TALER_ARL_SET_PP (wire_reserve_close_id), + NULL); + if (0 > qs) + goto handle_db_error; + qs = TALER_ARL_adb->insert_auditor_progress ( + TALER_ARL_adb->cls, + TALER_ARL_SET_PP (wire_reserve_close_id), + NULL); + if (0 > qs) + goto handle_db_error; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Concluded audit step at %llu/%llu\n", - (unsigned long long) TALER_ARL_USE_PP (wire_aggregation_id), - (unsigned long long) TALER_ARL_USE_PP (wire_batch_deposit_id)); - - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) - { - qs = TALER_ARL_edb->commit (TALER_ARL_edb->cls); - if (0 > qs) - { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Exchange DB commit failed, rolling back transaction\n"); - TALER_ARL_adb->rollback (TALER_ARL_adb->cls); - } - else - { - qs = TALER_ARL_adb->commit (TALER_ARL_adb->cls); - if (0 > qs) - { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Auditor DB commit failed!\n"); - } - } - } - else + "Concluded audit step at %llu\n", + (unsigned long long) TALER_ARL_USE_PP (wire_reserve_close_id)); + qs = TALER_ARL_adb->commit (TALER_ARL_adb->cls); + if (0 > qs) + goto handle_db_error; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Transaction concluded!\n"); + if (1 == test_mode) + GNUNET_SCHEDULER_shutdown (); + return; +handle_db_error: + TALER_ARL_adb->rollback (TALER_ARL_adb->cls); + for (unsigned int max_retries = 3; max_retries>0; max_retries--) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Processing failed, rolling back transaction\n"); - TALER_ARL_adb->rollback (TALER_ARL_adb->cls); - TALER_ARL_edb->rollback (TALER_ARL_edb->cls); + if (GNUNET_DB_STATUS_HARD_ERROR == qs) + break; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Serialization issue, trying again\n"); + qs = begin_transaction (); } - return; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Hard database error, terminating\n"); + GNUNET_SCHEDULER_shutdown (); } -/* ******************** Analyze required outgoing transfers ******************** */ - -/** - * Closure for import_wire_missing_cb(). - */ -struct ImportMissingWireContext -{ - /** - * Set to maximum row ID encountered. - */ - uint64_t max_batch_deposit_uuid; - - /** - * Set to database errors in callback. - */ - enum GNUNET_DB_QueryStatus err; -}; - - /** - * Function called on deposits that need to be checked for their - * wire transfer. + * Check that @a want is within #TIME_TOLERANCE of @a have. + * Otherwise report an inconsistency in row @a rowid of @a table. * - * @param cls closure, points to a `struct ImportMissingWireContext` - * @param batch_deposit_serial_id serial of the entry in the batch deposits table - * @param total_amount value of the missing deposits, including fee - * @param wire_target_h_payto where should the funds be wired - * @param deadline what was the earliest requested wire transfer deadline + * @param table where is the inconsistency (if any) + * @param rowid what is the row + * @param want what is the expected time + * @param have what is the time we got + * @return true on success, false to abort */ -static void -import_wire_missing_cb ( - void *cls, - uint64_t batch_deposit_serial_id, - const struct TALER_Amount *total_amount, - const struct TALER_PaytoHashP *wire_target_h_payto, - struct GNUNET_TIME_Timestamp deadline) +static bool +check_time_difference (const char *table, + uint64_t rowid, + struct GNUNET_TIME_Timestamp want, + struct GNUNET_TIME_Timestamp have) { - struct ImportMissingWireContext *wc = cls; - enum GNUNET_DB_QueryStatus qs; - - if (wc->err < 0) - return; /* already failed */ - GNUNET_assert (batch_deposit_serial_id > wc->max_batch_deposit_uuid); - wc->max_batch_deposit_uuid = batch_deposit_serial_id; - qs = TALER_ARL_adb->insert_pending_deposit ( - TALER_ARL_adb->cls, - batch_deposit_serial_id, - wire_target_h_payto, - total_amount, - deadline); - if (qs < 0) - wc->err = qs; -} - + struct GNUNET_TIME_Relative delta; + char *details; -/** - * Information about a delayed wire transfer and the possible - * reasons for the delay. - */ -struct ReasonDetail -{ - /** - * Batch deposit that may be lacking a wire transfer. - */ - uint64_t batch_deposit_serial_id; + if (GNUNET_TIME_timestamp_cmp (have, >, want)) + delta = GNUNET_TIME_absolute_get_difference (want.abs_time, + have.abs_time); + else + delta = GNUNET_TIME_absolute_get_difference (have.abs_time, + want.abs_time); + if (GNUNET_TIME_relative_cmp (delta, + <=, + TIME_TOLERANCE)) + return true; - /** - * Total amount that should have been transferred. - */ - struct TALER_Amount total_amount; + GNUNET_asprintf (&details, + "execution date mismatch (%s)", + GNUNET_TIME_relative2s (delta, + true)); + { + struct TALER_AUDITORDB_RowMinorInconsistencies rmi = { + .row_table = (char *) table, + .problem_row = rowid, + .diagnostic = details + }; + enum GNUNET_DB_QueryStatus qs; - /** - * Earliest deadline for an expected transfer to the account. - */ - struct GNUNET_TIME_Timestamp deadline; + qs = TALER_ARL_adb->insert_row_minor_inconsistencies ( + TALER_ARL_adb->cls, + &rmi); - /** - * Target account hash. - */ - struct TALER_PaytoHashP wire_target_h_payto; + if (qs < 0) + { + global_qs = qs; + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + GNUNET_free (details); + return false; + } + } + GNUNET_free (details); + return true; +} -}; /** - * Closure for report_wire_missing_cb(). + * Closure for #check_rc_matches */ -struct ReportMissingWireContext +struct CheckMatchContext { - /** - * Map from wire_target_h_payto to `struct ReasonDetail`. - */ - struct GNUNET_CONTAINER_MultiShortmap *map; - - /** - * Set to database errors in callback. - */ - enum GNUNET_DB_QueryStatus err; -}; - -/** - * Closure for #clear_finished_transfer_cb(). - */ -struct AggregationContext -{ /** - * Set to maximum row ID encountered. + * Reserve operation looking for a match */ - uint64_t max_aggregation_serial; + const struct ReserveOutInfo *roi; /** - * Set to database errors in callback. + * Set to true if we found a match. */ - enum GNUNET_DB_QueryStatus err; + bool found; }; /** - * Free memory allocated in @a value. - * - * @param cls unused - * @param key unused - * @param value must be a `struct ReasonDetail` - * @return #GNUNET_YES if we should continue to - * iterate, - * #GNUNET_NO if not. - */ -static enum GNUNET_GenericReturnValue -free_report_entry (void *cls, - const struct GNUNET_ShortHashCode *key, - void *value) -{ - struct ReasonDetail *rd = value; - - GNUNET_free (rd); - return GNUNET_YES; -} - - -/** - * We had an entry in our map of wire transfers that - * should have been performed. Generate report. + * Check if any of the reserve closures match the given wire transfer. * - * @param cls unused - * @param key unused - * @param value must be a `struct ReasonDetail` - * @return #GNUNET_YES if we should continue to - * iterate, - * #GNUNET_NO if not. + * @param[in,out] cls a `struct CheckMatchContext` + * @param key key of @a value in #reserve_closures + * @param value a `struct ReserveClosure` */ static enum GNUNET_GenericReturnValue -generate_report (void *cls, - const struct GNUNET_ShortHashCode *key, - void *value) +check_rc_matches (void *cls, + const struct GNUNET_HashCode *key, + void *value) { - struct ReasonDetail *rd = value; - - - /* For now, we simplify and only check that the - amount was tiny */ - if (0 > TALER_amount_cmp (&rd->total_amount, - &tiny_amount)) - return free_report_entry (cls, - key, - value); /* acceptable, amount was tiny */ + struct CheckMatchContext *cmx = cls; + struct ReserveClosure *rc = value; - // TODO: maybe split total_amount_lag up by category below? - TALER_ARL_amount_add (&TALER_ARL_USE_AB (total_amount_lag), - &TALER_ARL_USE_AB (total_amount_lag), - &rd->total_amount); + if ((0 == GNUNET_memcmp (&cmx->roi->details.wtid, + &rc->wtid)) && + (0 == strcasecmp (rc->receiver_account, + cmx->roi->details.credit_account_uri)) && + (0 == TALER_amount_cmp (&rc->amount, + &cmx->roi->details.amount))) { - enum GNUNET_DB_QueryStatus qs; - - qs = TALER_ARL_adb->insert_pending_deposit ( - TALER_ARL_adb->cls, - rd->batch_deposit_serial_id, - &rd->wire_target_h_payto, - &rd->total_amount, - rd->deadline); - if (qs < 0) + if (! check_time_difference ("reserves_closures", + rc->rowid, + rc->execution_date, + cmx->roi->details.execution_date)) { - global_qs = qs; - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + free_rc (NULL, + key, + rc); return GNUNET_SYSERR; } + cmx->found = true; + free_rc (NULL, + key, + rc); + return GNUNET_NO; } - return free_report_entry (cls, - key, - value); + return GNUNET_OK; } /** - * Function called on deposits that are past their due date - * and have not yet seen a wire transfer. + * Maximum required length for make_missing_diag(). + */ +#define MAX_DIAG_LEN 128 + +/** + * Make diagnostic string for missing wire transfer. * - * @param cls closure, points to a `struct ReportMissingWireContext` - * @param batch_deposit_serial_id row in the database for which the wire transfer is missing - * @param total_amount value of the missing deposits, including fee - * @param wire_target_h_payto hash of payto-URI where the funds should have been wired - * @param deadline what was the earliest requested wire transfer deadline + * @param[out] diag where to write the diagnostic string + * @param wtid wire transfer ID to include */ static void -report_wire_missing_cb ( - void *cls, - uint64_t batch_deposit_serial_id, - const struct TALER_Amount *total_amount, - const struct TALER_PaytoHashP *wire_target_h_payto, - struct GNUNET_TIME_Timestamp deadline) +make_missing_diag (char diag[MAX_DIAG_LEN], + const struct TALER_WireTransferIdentifierRawP *wtid) { - struct ReportMissingWireContext *rc = cls; - struct ReasonDetail *rd; - - rd = GNUNET_CONTAINER_multishortmap_get (rc->map, - &wire_target_h_payto->hash); - if (NULL == rd) - { - rd = GNUNET_new (struct ReasonDetail); - rd->batch_deposit_serial_id = batch_deposit_serial_id; - rd->wire_target_h_payto = *wire_target_h_payto; - rd->total_amount = *total_amount; - rd->deadline = deadline; - GNUNET_assert (GNUNET_YES == - GNUNET_CONTAINER_multishortmap_put ( - rc->map, - &wire_target_h_payto->hash, - rd, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); - } - else - { - TALER_ARL_amount_add (&rd->total_amount, - &rd->total_amount, - total_amount); - rd->deadline = GNUNET_TIME_timestamp_min (rd->deadline, - deadline); - } + char *wtid_s; + + wtid_s = GNUNET_STRINGS_data_to_string_alloc (wtid, + sizeof (*wtid)); + GNUNET_snprintf (diag, + MAX_DIAG_LEN, + "expected outgoing wire transfer %s missing", + wtid_s); + GNUNET_free (wtid_s); } /** - * Function called on aggregations that were done for - * a (batch) deposit. + * Check if an existing report on a missing wire + * out operation justified the @a roi. If so, + * clear the existing report. * - * @param cls closure - * @param tracking_serial_id where in the table are we - * @param batch_deposit_serial_id which batch deposit was aggregated + * @param roi reserve out operation to check + * @return #GNUNET_YES if @a roi was justified by a previous report, + * #GNUNET_NO of @a roi was not justified by a previous missing report + * #GNUNET_SYSERR on database trouble */ -static void -clear_finished_transfer_cb ( - void *cls, - uint64_t tracking_serial_id, - uint64_t batch_deposit_serial_id) +static enum GNUNET_GenericReturnValue +check_reported_inconsistency (struct ReserveOutInfo *roi) { - struct AggregationContext *ac = cls; + char diag[MAX_DIAG_LEN]; + struct TALER_AUDITORDB_WireOutInconsistency woi = { + .wire_out_row_id = roi->details.serial_id, + .destination_account = (char *) roi->details.credit_account_uri, + .diagnostic = diag, + .expected = roi->details.amount, + .claimed = zero, + }; enum GNUNET_DB_QueryStatus qs; - if (0 > ac->err) - return; /* already failed */ - GNUNET_assert (ac->max_aggregation_serial < tracking_serial_id); - ac->max_aggregation_serial = tracking_serial_id; - qs = TALER_ARL_adb->delete_pending_deposit ( + make_missing_diag (diag, + &roi->details.wtid); + qs = TALER_ARL_adb->delete_wire_out_inconsistency_if_matching ( TALER_ARL_adb->cls, - batch_deposit_serial_id); - if (0 == qs) + &woi); + if (qs < 0) { - /* Aggregated something twice or other error, report! */ - GNUNET_break (0); - // FIXME: report more nicely! + global_qs = qs; + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return GNUNET_SYSERR; } - if (0 > qs) - ac->err = qs; + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Deletion of wire out inconsistency %llu (%s, %s, %s) failed: not reported missing!\n", + (unsigned long long) roi->details.serial_id, + roi->details.credit_account_uri, + diag, + TALER_amount2s (&roi->details.amount)); + return GNUNET_NO; + } + TALER_ARL_amount_subtract (&TALER_ARL_USE_AB (total_bad_amount_out_minus), + &TALER_ARL_USE_AB (total_bad_amount_out_minus), + &roi->details.amount); + return GNUNET_YES; } /** - * Checks that all wire transfers that should have happened - * (based on deposits) have indeed happened. + * Check if a profit drain operation justified the @a roi + * + * @param roi reserve out operation to check + * @return #GNUNET_YES if @a roi was justified by a profit drain, + * #GNUNET_NO of @a roi was not justified by a proft drain + * #GNUNET_SYSERR on database trouble */ -static void -check_for_required_transfers (void) +static enum GNUNET_GenericReturnValue +check_profit_drain (struct ReserveOutInfo *roi) { - struct ImportMissingWireContext wc = { - .max_batch_deposit_uuid = TALER_ARL_USE_PP (wire_batch_deposit_id), - .err = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT - }; - struct GNUNET_TIME_Absolute deadline; enum GNUNET_DB_QueryStatus qs; - struct ReportMissingWireContext rc = { - .err = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT - }; - struct AggregationContext ac = { - .max_aggregation_serial = TALER_ARL_USE_PP (wire_aggregation_id), - .err = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT - }; + uint64_t serial; + char *account_section; + char *payto_uri; + struct GNUNET_TIME_Timestamp request_timestamp; + struct TALER_Amount amount; + struct TALER_MasterSignatureP master_sig; - qs = TALER_ARL_edb->select_batch_deposits_missing_wire ( + qs = TALER_ARL_edb->get_drain_profit ( TALER_ARL_edb->cls, - TALER_ARL_USE_PP (wire_batch_deposit_id), - &import_wire_missing_cb, - &wc); - if ((0 > qs) || (0 > wc.err)) + &roi->details.wtid, + &serial, + &account_section, + &payto_uri, + &request_timestamp, + &amount, + &master_sig); + switch (qs) { + case GNUNET_DB_STATUS_HARD_ERROR: GNUNET_break (0); - GNUNET_break ((GNUNET_DB_STATUS_SOFT_ERROR == qs) || - (GNUNET_DB_STATUS_SOFT_ERROR == wc.err)); global_ret = EXIT_FAILURE; GNUNET_SCHEDULER_shutdown (); - return; - } - TALER_ARL_USE_PP (wire_batch_deposit_id) = wc.max_batch_deposit_uuid; - qs = TALER_ARL_edb->select_aggregations_above_serial ( - TALER_ARL_edb->cls, - TALER_ARL_USE_PP (wire_aggregation_id), - &clear_finished_transfer_cb, - &ac); - if ((0 > qs) || (0 > ac.err)) - { + return GNUNET_SYSERR; + case GNUNET_DB_STATUS_SOFT_ERROR: + /* should fail on commit later ... */ GNUNET_break (0); - GNUNET_break ((GNUNET_DB_STATUS_SOFT_ERROR == qs) || - (GNUNET_DB_STATUS_SOFT_ERROR == ac.err)); - global_ret = EXIT_FAILURE; - GNUNET_SCHEDULER_shutdown (); - return; + return GNUNET_SYSERR; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + /* not a profit drain */ + return GNUNET_NO; + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + break; } - TALER_ARL_USE_PP (wire_aggregation_id) = ac.max_aggregation_serial; - /* Subtract #GRACE_PERIOD, so we can be a bit behind in processing - without immediately raising undue concern */ - deadline = GNUNET_TIME_absolute_subtract (GNUNET_TIME_absolute_get (), - GRACE_PERIOD); - rc.map = GNUNET_CONTAINER_multishortmap_create (1024, - GNUNET_NO); - qs = TALER_ARL_adb->select_pending_deposits ( - TALER_ARL_adb->cls, - deadline, - &report_wire_missing_cb, - &rc); - if ((0 > qs) || (0 > rc.err)) + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Profit drain of %s to %s found!\n", + TALER_amount2s (&amount), + payto_uri); + if (GNUNET_OK != + TALER_exchange_offline_profit_drain_verify ( + &roi->details.wtid, + request_timestamp, + &amount, + account_section, + payto_uri, + &TALER_ARL_master_pub, + &master_sig)) { + struct TALER_AUDITORDB_RowInconsistency ri = { + .row_id = roi->details.serial_id, + .row_table = "profit_drains", + .diagnostic = "invalid signature" + }; + GNUNET_break (0); - GNUNET_break ((GNUNET_DB_STATUS_SOFT_ERROR == qs) || - (GNUNET_DB_STATUS_SOFT_ERROR == rc.err)); - GNUNET_CONTAINER_multishortmap_iterate (rc.map, - &free_report_entry, - NULL); - GNUNET_CONTAINER_multishortmap_destroy (rc.map); - global_ret = EXIT_FAILURE; - GNUNET_SCHEDULER_shutdown (); - return; - } - GNUNET_CONTAINER_multishortmap_iterate (rc.map, - &generate_report, - NULL); - GNUNET_CONTAINER_multishortmap_destroy (rc.map); - /* conclude with success */ - commit (global_qs); - if (test_mode) - { - GNUNET_SCHEDULER_shutdown (); - return; + qs = TALER_ARL_adb->insert_row_inconsistency ( + TALER_ARL_adb->cls, + &ri); + GNUNET_free (payto_uri); + GNUNET_free (account_section); + if (qs < 0) + { + global_qs = qs; + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return GNUNET_SYSERR; + } + return GNUNET_NO; } -} + GNUNET_free (account_section); + { + char *np = TALER_payto_normalize (payto_uri); -/* ***************************** Analyze reserves_out ************************ */ + if (0 != + strcasecmp (np, + roi->details.credit_account_uri)) + { + struct TALER_AUDITORDB_WireOutInconsistency woi = { + .wire_out_row_id = serial, + .destination_account = (char *) roi->details.credit_account_uri, + .diagnostic = "profit drain wired to invalid account", + .expected = roi->details.amount, + .claimed = zero, + }; + + GNUNET_free (np); + qs = TALER_ARL_adb->insert_wire_out_inconsistency ( + TALER_ARL_adb->cls, + &woi); + if (qs < 0) + { + global_qs = qs; + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + GNUNET_free (payto_uri); + return GNUNET_SYSERR; + } + TALER_ARL_amount_add (&TALER_ARL_USE_AB (total_bad_amount_out_plus), + &TALER_ARL_USE_AB (total_bad_amount_out_plus), + &amount); + GNUNET_free (payto_uri); + return GNUNET_YES; /* justified, kind-of */ + } + GNUNET_free (np); + } + GNUNET_free (payto_uri); + if (0 != + TALER_amount_cmp (&amount, + &roi->details.amount)) + { + struct TALER_AUDITORDB_WireOutInconsistency woi = { + .wire_out_row_id = roi->details.serial_id, + .destination_account = (char *) roi->details.credit_account_uri, + .diagnostic = "incorrect amount drained to correct account", + .expected = roi->details.amount, + .claimed = amount, + }; -/** - * Clean up after processing wire out data. - */ -static void -conclude_wire_out (void) -{ - GNUNET_CONTAINER_multihashmap_destroy (out_map); - out_map = NULL; - check_for_required_transfers (); + qs = TALER_ARL_adb->insert_wire_out_inconsistency ( + TALER_ARL_adb->cls, + &woi); + if (qs < 0) + { + global_qs = qs; + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return GNUNET_SYSERR; + } + TALER_ARL_amount_add (&TALER_ARL_USE_AB (total_bad_amount_out_minus), + &TALER_ARL_USE_AB (total_bad_amount_out_minus), + &roi->details.amount); + TALER_ARL_amount_add (&TALER_ARL_USE_AB (total_bad_amount_out_plus), + &TALER_ARL_USE_AB (total_bad_amount_out_plus), + &amount); + return GNUNET_YES; /* justified, kind-of */ + } + /* profit drain was correct */ + TALER_ARL_amount_add (&TALER_ARL_USE_AB (total_drained), + &TALER_ARL_USE_AB (total_drained), + &amount); + return GNUNET_YES; } /** - * Check that @a want is within #TIME_TOLERANCE of @a have. - * Otherwise report an inconsistency in row @a rowid of @a table. + * Check whether the given transfer was justified by a reserve closure or + * profit drain. If not, complain that we failed to match an entry from + * #out_map. This means a wire transfer was made without proper + * justification. * - * @param table where is the inconsistency (if any) - * @param rowid what is the row - * @param want what is the expected time - * @param have what is the time we got - * @return true on success, false to abort + * @param cls a `struct WireAccount` + * @param key unused key + * @param value the `struct ReserveOutInfo` to report + * @return #GNUNET_OK on success */ -static bool -check_time_difference (const char *table, - uint64_t rowid, - struct GNUNET_TIME_Timestamp want, - struct GNUNET_TIME_Timestamp have) +static enum GNUNET_GenericReturnValue +complain_out_not_found (void *cls, + const struct GNUNET_HashCode *key, + void *value) { - struct GNUNET_TIME_Relative delta; - char *details; + // struct WireAccount *wa = cls; + struct ReserveOutInfo *roi = value; + struct GNUNET_HashCode rkey; + struct CheckMatchContext cmx = { + .roi = roi, + .found = false + }; + enum GNUNET_GenericReturnValue ret; + + (void) cls; + (void) key; + hash_rc (roi->details.credit_account_uri, + &roi->details.wtid, + &rkey); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Checking for reserve closure %s benefiting %s\n", + GNUNET_h2s (&rkey), + roi->details.credit_account_uri); + GNUNET_CONTAINER_multihashmap_get_multiple (reserve_closures, + &rkey, + &check_rc_matches, + &cmx); + if (cmx.found) + return GNUNET_OK; + ret = check_reported_inconsistency (roi); + if (GNUNET_NO != ret) + return ret; + ret = check_profit_drain (roi); + if (GNUNET_NO != ret) + return ret; - if (GNUNET_TIME_timestamp_cmp (have, >, want)) - delta = GNUNET_TIME_absolute_get_difference (want.abs_time, - have.abs_time); - else - delta = GNUNET_TIME_absolute_get_difference (have.abs_time, - want.abs_time); - if (GNUNET_TIME_relative_cmp (delta, - <=, - TIME_TOLERANCE)) - return true; - GNUNET_asprintf (&details, - "execution date mismatch (%s)", - GNUNET_TIME_relative2s (delta, - true)); { - struct TALER_AUDITORDB_RowMinorInconsistencies rmi = { - .row_id = rowid, - .diagnostic = details, - .row_table = (char *) table + struct TALER_AUDITORDB_WireOutInconsistency woi = { + .destination_account = (char *) roi->details.credit_account_uri, + .diagnostic = "missing justification for outgoing wire transfer", + .wire_out_row_id = roi->details.serial_id, + .expected = zero, + .claimed = roi->details.amount }; enum GNUNET_DB_QueryStatus qs; - qs = TALER_ARL_adb->insert_row_minor_inconsistencies ( + qs = TALER_ARL_adb->insert_wire_out_inconsistency ( TALER_ARL_adb->cls, - &rmi); - + &woi); if (qs < 0) { global_qs = qs; GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - GNUNET_free (details); - return false; + return GNUNET_SYSERR; } } - GNUNET_free (details); - return true; + TALER_ARL_amount_add (&TALER_ARL_USE_AB (total_bad_amount_out_plus), + &TALER_ARL_USE_AB (total_bad_amount_out_plus), + &roi->details.amount); + return GNUNET_OK; } @@ -1077,7 +1057,7 @@ check_time_difference (const char *table, * as claimed by the exchange DB. * * @param cls a `struct WireAccount` - * @param rowid unique serial ID for the refresh session in our DB + * @param rowid unique serial ID in wire_out table * @param date timestamp of the transfer (roughly) * @param wtid wire transfer subject * @param payto_uri wire transfer details of the receiver @@ -1085,23 +1065,26 @@ check_time_difference (const char *table, * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop */ static enum GNUNET_GenericReturnValue -wire_out_cb (void *cls, - uint64_t rowid, - struct GNUNET_TIME_Timestamp date, - const struct TALER_WireTransferIdentifierRawP *wtid, - const char *payto_uri, - const struct TALER_Amount *amount) +wire_out_cb ( + void *cls, + uint64_t rowid, + struct GNUNET_TIME_Timestamp date, + const struct TALER_WireTransferIdentifierRawP *wtid, + const char *payto_uri, + const struct TALER_Amount *amount) { struct WireAccount *wa = cls; struct GNUNET_HashCode key; struct ReserveOutInfo *roi; - enum GNUNET_GenericReturnValue ret = GNUNET_OK; + char *np = TALER_payto_normalize (payto_uri); GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Exchange wire OUT at %s of %s with WTID %s\n", + "Exchange wire OUT #%llu at %s of %s with WTID %s\n", + (unsigned long long) rowid, GNUNET_TIME_timestamp2s (date), TALER_amount2s (amount), TALER_B2S (wtid)); + wa->last_wire_out_serial_id = rowid + 1; TALER_ARL_amount_add (&TALER_ARL_USE_AB (total_wire_out), &TALER_ARL_USE_AB (total_wire_out), amount); @@ -1113,21 +1096,30 @@ wire_out_cb (void *cls, if (NULL == roi) { /* Wire transfer was not made (yet) at all (but would have been - justified), so the entire amount is missing / still to be done. - This is moderately harmless, it might just be that the aggregator - has not yet fully caught up with the transfers it should do. */ + justified), so the entire amount is missing / still to be done. This + is moderately harmless, it might just be that the + taler-exchange-transfer tool or bank has not yet fully caught up with + the transfers it should do. + May be cleared later by check_reported_inconsistency() */ + char diag[MAX_DIAG_LEN]; struct TALER_AUDITORDB_WireOutInconsistency woi = { - .row_id = rowid, - .destination_account = (char *) payto_uri, - .diagnostic = "expected wire transfer missing", + .destination_account = np, + .diagnostic = diag, + .wire_out_row_id = rowid, .expected = *amount, .claimed = zero, }; enum GNUNET_DB_QueryStatus qs; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Wire out for row %llu still missing\n", + (unsigned long long) rowid); + make_missing_diag (diag, + wtid); qs = TALER_ARL_adb->insert_wire_out_inconsistency ( TALER_ARL_adb->cls, &woi); + GNUNET_free (np); if (qs < 0) { global_qs = qs; @@ -1139,24 +1131,26 @@ wire_out_cb (void *cls, amount); return GNUNET_OK; } - if (0 != strcasecmp (payto_uri, + + if (0 != strcasecmp (np, roi->details.credit_account_uri)) { /* Destination bank account is wrong in actual wire transfer, so we should count the wire transfer as entirely spurious, and additionally consider the justified wire transfer as missing. */ struct TALER_AUDITORDB_WireOutInconsistency woi = { - .row_id = rowid, - .destination_account = (char *) payto_uri, + .wire_out_row_id = rowid, + .destination_account = np, .diagnostic = "receiver account mismatch", .expected = *amount, - .claimed = zero, + .claimed = roi->details.amount, }; enum GNUNET_DB_QueryStatus qs; qs = TALER_ARL_adb->insert_wire_out_inconsistency ( TALER_ARL_adb->cls, &woi); + GNUNET_free (np); if (qs < 0) { global_qs = qs; @@ -1169,23 +1163,29 @@ wire_out_cb (void *cls, TALER_ARL_amount_add (&TALER_ARL_USE_AB (total_bad_amount_out_minus), &TALER_ARL_USE_AB (total_bad_amount_out_minus), amount); + GNUNET_assert (GNUNET_OK == + free_roi (NULL, + &key, + roi)); return GNUNET_OK; } + if (0 != TALER_amount_cmp (&roi->details.amount, amount)) { struct TALER_AUDITORDB_WireOutInconsistency woi = { - .row_id = rowid, - .destination_account = (char *) payto_uri, + .destination_account = np, .diagnostic = "wire amount does not match", + .wire_out_row_id = rowid, .expected = *amount, - .claimed = zero, + .claimed = roi->details.amount, }; enum GNUNET_DB_QueryStatus qs; qs = TALER_ARL_adb->insert_wire_out_inconsistency ( TALER_ARL_adb->cls, &woi); + GNUNET_free (np); if (qs < 0) { global_qs = qs; @@ -1217,271 +1217,35 @@ wire_out_cb (void *cls, &TALER_ARL_USE_AB (total_bad_amount_out_plus), &delta); } + GNUNET_assert (GNUNET_OK == + free_roi (NULL, + &key, + roi)); return GNUNET_OK; } - if (! check_time_difference ("wire_out", - rowid, - date, - roi->details.execution_date)) - ret = GNUNET_SYSERR; - GNUNET_assert (GNUNET_OK == - free_roi (NULL, - &key, - roi)); - wa->last_wire_out_serial_id = rowid + 1; - return ret; -} - - -/** - * Closure for #check_rc_matches - */ -struct CheckMatchContext -{ - - /** - * Reserve operation looking for a match - */ - const struct ReserveOutInfo *roi; - - /** - * Set to true if we found a match. - */ - bool found; -}; - - -/** - * Check if any of the reserve closures match the given wire transfer. - * - * @param[in,out] cls a `struct CheckMatchContext` - * @param key key of @a value in #reserve_closures - * @param value a `struct ReserveClosure` - */ -static enum GNUNET_GenericReturnValue -check_rc_matches (void *cls, - const struct GNUNET_HashCode *key, - void *value) -{ - struct CheckMatchContext *ctx = cls; - struct ReserveClosure *rc = value; - - if ((0 == GNUNET_memcmp (&ctx->roi->details.wtid, - &rc->wtid)) && - (0 == strcasecmp (rc->receiver_account, - ctx->roi->details.credit_account_uri)) && - (0 == TALER_amount_cmp (&rc->amount, - &ctx->roi->details.amount))) { - if (! check_time_difference ("reserves_closures", - rc->rowid, - rc->execution_date, - ctx->roi->details.execution_date)) - { - free_rc (NULL, - key, - rc); - return GNUNET_SYSERR; - } - ctx->found = true; - free_rc (NULL, - key, - rc); - return GNUNET_NO; - } - return GNUNET_OK; -} - + enum GNUNET_GenericReturnValue ret; -/** - * Check whether the given transfer was justified by a reserve closure or - * profit drain. If not, complain that we failed to match an entry from - * #out_map. This means a wire transfer was made without proper - * justification. - * - * @param cls a `struct WireAccount` - * @param key unused key - * @param value the `struct ReserveOutInfo` to report - * @return #GNUNET_OK on success - */ -static enum GNUNET_GenericReturnValue -complain_out_not_found (void *cls, - const struct GNUNET_HashCode *key, - void *value) -{ - // struct WireAccount *wa = cls; - struct ReserveOutInfo *roi = value; - struct GNUNET_HashCode rkey; - struct CheckMatchContext ctx = { - .roi = roi, - .found = false - }; - - (void) key; - hash_rc (roi->details.credit_account_uri, - &roi->details.wtid, - &rkey); - GNUNET_CONTAINER_multihashmap_get_multiple (reserve_closures, - &rkey, - &check_rc_matches, - &ctx); - if (ctx.found) - return GNUNET_OK; - /* check for profit drain */ - { - enum GNUNET_DB_QueryStatus qs; - uint64_t serial; - char *account_section; - char *payto_uri; - struct GNUNET_TIME_Timestamp request_timestamp; - struct TALER_Amount amount; - struct TALER_MasterSignatureP master_sig; - - qs = TALER_ARL_edb->get_drain_profit (TALER_ARL_edb->cls, - &roi->details.wtid, - &serial, - &account_section, - &payto_uri, - &request_timestamp, - &amount, - &master_sig); - switch (qs) + if (! check_time_difference ("wire_out", + rowid, + date, + roi->details.execution_date)) { - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - global_ret = EXIT_FAILURE; - GNUNET_SCHEDULER_shutdown (); - return GNUNET_SYSERR; - case GNUNET_DB_STATUS_SOFT_ERROR: - /* should fail on commit later ... */ - GNUNET_break (0); - return GNUNET_NO; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - /* not a profit drain */ - break; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Profit drain of %s to %s found!\n", - TALER_amount2s (&amount), - payto_uri); - if (GNUNET_OK != - TALER_exchange_offline_profit_drain_verify ( - &roi->details.wtid, - request_timestamp, - &amount, - account_section, - payto_uri, - &TALER_ARL_master_pub, - &master_sig)) - { - struct TALER_AUDITORDB_RowInconsistency ri = { - .row_id = roi->details.serial_id, - .row_table = "profit_drains", - .diagnostic = "invalid signature" - }; - - GNUNET_break (0); - qs = TALER_ARL_adb->insert_row_inconsistency ( - TALER_ARL_adb->cls, - &ri); - if (qs < 0) - { - global_qs = qs; - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - return GNUNET_SYSERR; - } - TALER_ARL_amount_add (&TALER_ARL_USE_AB (total_bad_amount_out_plus), - &TALER_ARL_USE_AB (total_bad_amount_out_plus), - &amount); - } - else if (0 != - strcasecmp (payto_uri, - roi->details.credit_account_uri)) - { - struct TALER_AUDITORDB_WireOutInconsistency woi = { - .row_id = serial, - .destination_account = (char *) roi->details.credit_account_uri, - .diagnostic = "amount wired to invalid account", - .expected = roi->details.amount, - .claimed = zero, - }; - - qs = TALER_ARL_adb->insert_wire_out_inconsistency ( - TALER_ARL_adb->cls, - &woi); - if (qs < 0) - { - global_qs = qs; - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - return GNUNET_SYSERR; - } - TALER_ARL_amount_add (&TALER_ARL_USE_AB (total_bad_amount_out_plus), - &TALER_ARL_USE_AB (total_bad_amount_out_plus), - &amount); - } - else if (0 != - TALER_amount_cmp (&amount, - &roi->details.amount)) - { - struct TALER_AUDITORDB_WireOutInconsistency woi = { - .row_id = roi->details.serial_id, - .destination_account = (char *) roi->details.credit_account_uri, - .diagnostic = "incorrect amount to correct account", - .expected = roi->details.amount, - .claimed = amount, - }; - - qs = TALER_ARL_adb->insert_wire_out_inconsistency ( - TALER_ARL_adb->cls, - &woi); - if (qs < 0) - { - global_qs = qs; - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - return GNUNET_SYSERR; - } - TALER_ARL_amount_add (&TALER_ARL_USE_AB (total_bad_amount_out_minus), - &TALER_ARL_USE_AB (total_bad_amount_out_minus), - &roi->details.amount); - TALER_ARL_amount_add (&TALER_ARL_USE_AB (total_bad_amount_out_plus), - &TALER_ARL_USE_AB (total_bad_amount_out_plus), - &amount); - } - GNUNET_free (account_section); - GNUNET_free (payto_uri); - /* profit drain was correct */ - TALER_ARL_amount_add (&TALER_ARL_USE_AB (total_drained), - &TALER_ARL_USE_AB (total_drained), - &amount); - return GNUNET_OK; + /* We had a database error, fail */ + ret = GNUNET_SYSERR; } - } - - { - struct TALER_AUDITORDB_WireOutInconsistency woi = { - .row_id = roi->details.serial_id, - .destination_account = (char *) roi->details.credit_account_uri, - .diagnostic = "missing justification for outgoing wire transfer", - .expected = zero, - .claimed =roi->details.amount - }; - enum GNUNET_DB_QueryStatus qs; - - qs = TALER_ARL_adb->insert_wire_out_inconsistency ( - TALER_ARL_adb->cls, - &woi); - if (qs < 0) + else { - global_qs = qs; - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - return GNUNET_SYSERR; + ret = GNUNET_OK; } + GNUNET_assert (GNUNET_OK == + free_roi (NULL, + &key, + roi)); + GNUNET_free (np); + return ret; } - TALER_ARL_amount_add (&TALER_ARL_USE_AB (total_bad_amount_out_plus), - &TALER_ARL_USE_AB (total_bad_amount_out_plus), - &roi->details.amount); - return GNUNET_OK; } @@ -1490,17 +1254,17 @@ complain_out_not_found (void *cls, * the DEBIT transactions this time, and then verify that all of them are * justified by 'reserves_out'. * - * @param cls `struct WireAccount` with a wire account list to process + * @param[in,out] wa wire account list to process */ static void -process_debits (void *cls); +process_debits (struct WireAccount *wa); /** * Go over the "wire_out" table of the exchange and * verify that all wire outs are in that table. * - * @param wa wire account we are processing + * @param[in,out] wa wire account we are processing */ static void check_exchange_wire_out (struct WireAccount *wa) @@ -1544,14 +1308,67 @@ check_exchange_wire_out (struct WireAccount *wa) * @param dhr HTTP response details */ static void -history_debit_cb (void *cls, - const struct TALER_BANK_DebitHistoryResponse *dhr) +history_debit_cb ( + void *cls, + const struct TALER_BANK_DebitHistoryResponse *dhr); + + +/** + * Task scheduled to begin long-polling on the + * bank transfer. + * + * @param cls a `struct WireAccount *` + */ +static void +dh_long_poll (void *cls) +{ + struct WireAccount *wa = cls; + + wa->dhh_task = NULL; + wa->dhh_next + = GNUNET_TIME_relative_to_absolute (MIN_LONGPOLL_DELAY); + GNUNET_assert (NULL == wa->dhh); + wa->dhh = TALER_BANK_debit_history ( + ctx, + wa->ai->auth, + wa->wire_off_out, + MAX_PER_TRANSACTION, + MAX_LONGPOLL_DELAY, + &history_debit_cb, + wa); + if (NULL == wa->dhh) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to start long-polling for bank transaction history for `%s'\n", + wa->ai->section_name); + global_ret = EXIT_FAILURE; + GNUNET_SCHEDULER_shutdown (); + return; + } +} + + +static void +history_debit_cb ( + void *cls, + const struct TALER_BANK_DebitHistoryResponse *dhr) { struct WireAccount *wa = cls; struct ReserveOutInfo *roi; size_t slen; wa->dhh = NULL; + if ( (MHD_HTTP_OK == dhr->http_status) && + (0 != dhr->details.ok.details_length) ) + { + /* As we got results, we go again *immediately* */ + wa->dhh_next = GNUNET_TIME_UNIT_ZERO_ABS; + } + GNUNET_assert (NULL == wa->dhh_task); + wa->dhh_task + = GNUNET_SCHEDULER_add_at (wa->dhh_next, + &dh_long_poll, + wa); switch (dhr->http_status) { case MHD_HTTP_OK: @@ -1559,26 +1376,28 @@ history_debit_cb (void *cls, { const struct TALER_BANK_DebitDetails *dd = &dhr->details.ok.details[i]; + char *np = TALER_payto_normalize (dd->credit_account_uri); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Analyzing bank DEBIT at %s of %s with WTID %s\n", + "Analyzing bank DEBIT #%llu at %s of %s with WTID %s\n", + (unsigned long long) dd->serial_id, GNUNET_TIME_timestamp2s (dd->execution_date), TALER_amount2s (&dd->amount), TALER_B2S (&dd->wtid)); - /* Update offset */ - wa->wire_off_out = dd->serial_id; - slen = strlen (dd->credit_account_uri) + 1; + wa->wire_off_out = dd->serial_id + 1; + slen = strlen (np) + 1; roi = GNUNET_malloc (sizeof (struct ReserveOutInfo) + slen); GNUNET_CRYPTO_hash (&dd->wtid, sizeof (dd->wtid), &roi->subject_hash); - roi->details.amount = dd->amount; - roi->details.execution_date = dd->execution_date; - roi->details.wtid = dd->wtid; - roi->details.credit_account_uri = (const char *) &roi[1]; + roi->details = *dd; + roi->details.credit_account_uri + = (const char *) &roi[1]; GNUNET_memcpy (&roi[1], - dd->credit_account_uri, + np, slen); + GNUNET_free (np); if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (out_map, &roi->subject_hash, @@ -1586,17 +1405,15 @@ history_debit_cb (void *cls, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) { struct TALER_AUDITORDB_WireFormatInconsistency wfi = { - // fixme: rowid! - .diagnostic = "duplicate subject hash", .amount = dd->amount, - .wire_offset = dd->serial_id + .wire_offset = dd->serial_id, + .diagnostic = "duplicate outgoing wire transfer subject" }; enum GNUNET_DB_QueryStatus qs; qs = TALER_ARL_adb->insert_wire_format_inconsistency ( TALER_ARL_adb->cls, &wfi); - if (qs < 0) { global_qs = qs; @@ -1604,8 +1421,10 @@ history_debit_cb (void *cls, commit (qs); return; } - TALER_ARL_amount_add (&TALER_ARL_USE_AB (total_wire_format_amount), - &TALER_ARL_USE_AB (total_wire_format_amount), + TALER_ARL_amount_add (&TALER_ARL_USE_AB ( + wire_debit_duplicate_transfer_subject_total), + &TALER_ARL_USE_AB ( + wire_debit_duplicate_transfer_subject_total), &dd->amount); } } @@ -1632,77 +1451,55 @@ history_debit_cb (void *cls, commit (GNUNET_DB_STATUS_HARD_ERROR); global_ret = EXIT_FAILURE; GNUNET_SCHEDULER_shutdown (); + return; } -/** - * Main function for processing 'reserves_out' data. We start by going over - * the DEBIT transactions this time, and then verify that all of them are - * justified by 'reserves_out'. - * - * @param cls `struct WireAccount` with a wire account list to process - */ static void -process_debits (void *cls) +process_debits (struct WireAccount *wa) { - struct WireAccount *wa = cls; - /* skip accounts where DEBIT is not enabled */ while ( (NULL != wa) && - (GNUNET_NO == wa->ai->debit_enabled)) + (! wa->ai->debit_enabled) ) wa = wa->next; if (NULL == wa) { - /* end of iteration, now check wire_out to see - if it matches #out_map */ - conclude_wire_out (); + /* end of iteration */ + commit (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT); return; } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Checking bank DEBIT records of account `%s'\n", wa->ai->section_name); - GNUNET_assert (NULL == wa->dhh); - // FIXME: handle the case where more than INT32_MAX transactions exist. - // (CG: used to be INT64_MAX, changed by MS to INT32_MAX, why? To be discussed with him!) - wa->dhh = TALER_BANK_debit_history (ctx, - wa->ai->auth, - wa->wire_off_out, - INT32_MAX, - GNUNET_TIME_UNIT_ZERO, - &history_debit_cb, - wa); - if (NULL == wa->dhh) + if ( (NULL == wa->dhh) && + (NULL == wa->dhh_task) ) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to obtain bank transaction history for `%s'\n", - wa->ai->section_name); - commit (GNUNET_DB_STATUS_HARD_ERROR); - global_ret = EXIT_FAILURE; - GNUNET_SCHEDULER_shutdown (); - return; + wa->dhh = TALER_BANK_debit_history ( + ctx, + wa->ai->auth, + wa->wire_off_out, + MAX_PER_TRANSACTION, + GNUNET_TIME_UNIT_ZERO, + &history_debit_cb, + wa); + if (NULL == wa->dhh) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to obtain bank transaction history for `%s'\n", + wa->ai->section_name); + commit (GNUNET_DB_STATUS_HARD_ERROR); + global_ret = EXIT_FAILURE; + GNUNET_SCHEDULER_shutdown (); + return; + } } } /** - * Begin analyzing wire_out. - */ -static void -begin_debit_audit (void) -{ - GNUNET_assert (NULL == out_map); - out_map = GNUNET_CONTAINER_multihashmap_create (1024, - true); - process_debits (wa_head); -} - - -/* ***************************** Setup logic ************************ */ - -/** * Function called about reserve closing operations the aggregator triggered. * - * @param cls closure + * @param cls closure; NULL * @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 @@ -1715,21 +1512,24 @@ begin_debit_audit (void) * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop */ static enum GNUNET_GenericReturnValue -reserve_closed_cb (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 char *receiver_account, - const struct TALER_WireTransferIdentifierRawP *wtid, - uint64_t close_request_row) +reserve_closed_cb ( + 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 char *receiver_account, + const struct TALER_WireTransferIdentifierRawP *wtid, + uint64_t close_request_row) { struct ReserveClosure *rc; struct GNUNET_HashCode key; (void) cls; (void) close_request_row; + GNUNET_assert (TALER_ARL_USE_PP (wire_reserve_close_id) <= rowid); + TALER_ARL_USE_PP (wire_reserve_close_id) = rowid + 1; rc = GNUNET_new (struct ReserveClosure); if (TALER_ARL_SR_INVALID_NEGATIVE == TALER_ARL_amount_subtract_neg (&rc->amount, @@ -1737,8 +1537,9 @@ reserve_closed_cb (void *cls, closing_fee)) { struct TALER_AUDITORDB_RowInconsistency ri = { + .row_id = rowid, .row_table = "reserves_closures", - .diagnostic = "closing fee above total amount" + .diagnostic = "closing fee above reserve balance (and closed anyway)" }; enum GNUNET_DB_QueryStatus qs; @@ -1754,20 +1555,24 @@ reserve_closed_cb (void *cls, GNUNET_free (rc); return GNUNET_OK; } - TALER_ARL_USE_PP (wire_reserve_close_id) - = GNUNET_MAX (TALER_ARL_USE_PP (wire_reserve_close_id), - rowid + 1); - rc->receiver_account = GNUNET_strdup (receiver_account); + rc->receiver_account = TALER_payto_normalize (receiver_account); rc->wtid = *wtid; rc->execution_date = execution_date; rc->rowid = rowid; - hash_rc (receiver_account, + hash_rc (rc->receiver_account, wtid, &key); - (void) GNUNET_CONTAINER_multihashmap_put (reserve_closures, - &key, - rc, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Discovered reserve closure %llu (%s) over %s benefiting %s\n", + (unsigned long long) rowid, + GNUNET_h2s (&key), + TALER_amount2s (amount_with_fee), + receiver_account); + (void) GNUNET_CONTAINER_multihashmap_put ( + reserve_closures, + &key, + rc, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); return GNUNET_OK; } @@ -1803,10 +1608,9 @@ begin_transaction (void) GNUNET_break (0); return GNUNET_DB_STATUS_HARD_ERROR; } - TALER_ARL_edb->preflight (TALER_ARL_edb->cls); if (GNUNET_OK != - TALER_ARL_edb->start (TALER_ARL_edb->cls, - "wire auditor")) + TALER_ARL_edb->start_read_only (TALER_ARL_edb->cls, + "wire debit auditor")) { GNUNET_break (0); return GNUNET_DB_STATUS_HARD_ERROR; @@ -1817,9 +1621,8 @@ begin_transaction (void) TALER_ARL_GET_AB (total_wire_out), TALER_ARL_GET_AB (total_bad_amount_out_plus), TALER_ARL_GET_AB (total_bad_amount_out_minus), - TALER_ARL_GET_AB (total_amount_lag), TALER_ARL_GET_AB (total_closure_amount_lag), - TALER_ARL_GET_AB (total_wire_format_amount), + TALER_ARL_GET_AB (wire_debit_duplicate_transfer_subject_total), TALER_ARL_GET_AB (total_wire_out), NULL); switch (qs) @@ -1831,10 +1634,7 @@ begin_transaction (void) GNUNET_break (0); return qs; case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - had_start_balance = false; - break; case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - had_start_balance = true; break; } for (struct WireAccount *wa = wa_head; @@ -1849,64 +1649,60 @@ begin_transaction (void) "wire-%s-%s", wa->ai->section_name, "wire_off_out"); - wa->qsx = TALER_ARL_adb->get_auditor_progress ( + qs = TALER_ARL_adb->get_auditor_progress ( TALER_ARL_adb->cls, wa->label_wire_out_serial_id, &wa->last_wire_out_serial_id, wa->label_wire_off_out, &wa->wire_off_out, NULL); - if (0 > wa->qsx) + if (0 > qs) { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == wa->qsx); - return GNUNET_DB_STATUS_HARD_ERROR; + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; } + GNUNET_assert (2 == qs); wa->start_wire_out_serial_id = wa->last_wire_out_serial_id; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Resuming account %s debit audit at %llu/%llu\n", + wa->ai->section_name, + (unsigned long long) wa->last_wire_out_serial_id, + (unsigned long long) wa->wire_off_out); } - qsx_gwap = TALER_ARL_adb->get_auditor_progress ( + qs = TALER_ARL_adb->get_auditor_progress ( TALER_ARL_adb->cls, TALER_ARL_GET_PP (wire_reserve_close_id), - TALER_ARL_GET_PP (wire_batch_deposit_id), - TALER_ARL_GET_PP (wire_aggregation_id), NULL); - if (0 > qsx_gwap) + if (0 > qs) { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsx_gwap); - return GNUNET_DB_STATUS_HARD_ERROR; + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; } - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qsx_gwap) + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) { GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "First analysis of with wire auditor, starting audit from scratch\n"); } else { - if (TALER_ARL_USE_PP (wire_reserve_close_id) == 0) - had_start_progress = false; - else - had_start_progress = true; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Resuming wire audit at %llu / %llu / %llu\n", - (unsigned long long) TALER_ARL_USE_PP (wire_reserve_close_id), - (unsigned long long) TALER_ARL_USE_PP (wire_batch_deposit_id), - (unsigned long long) TALER_ARL_USE_PP (wire_aggregation_id)); + "Resuming wire debit audit at %llu\n", + (unsigned long long) TALER_ARL_USE_PP (wire_reserve_close_id)); } - + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Iterating over reserve closures from %llu\n", + (unsigned long long) TALER_ARL_USE_PP (wire_reserve_close_id)); + qs = TALER_ARL_edb->select_reserve_closed_above_serial_id ( + TALER_ARL_edb->cls, + TALER_ARL_USE_PP (wire_reserve_close_id), + &reserve_closed_cb, + NULL); + if (0 > qs) { - enum GNUNET_DB_QueryStatus qs; - - qs = TALER_ARL_edb->select_reserve_closed_above_serial_id ( - TALER_ARL_edb->cls, - TALER_ARL_USE_PP (wire_reserve_close_id), - &reserve_closed_cb, - NULL); - if (0 > qs) - { - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - return GNUNET_DB_STATUS_HARD_ERROR; - } + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); + return GNUNET_DB_STATUS_HARD_ERROR; } - begin_debit_audit (); + process_debits (wa_head); return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; } @@ -1926,8 +1722,8 @@ process_account_cb (void *cls, struct WireAccount *wa; (void) cls; - if ((! ai->debit_enabled) && - (! ai->credit_enabled)) + if ( (! ai->debit_enabled) && + (! ai->credit_enabled) ) return; /* not an active exchange account */ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Found exchange account `%s'\n", @@ -2016,8 +1812,8 @@ run (void *cls, GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule, - &rc); - rc = GNUNET_CURL_gnunet_rc_create (ctx); + &rctx); + rctx = GNUNET_CURL_gnunet_rc_create (ctx); if (NULL == ctx) { GNUNET_break (0); @@ -2026,6 +1822,8 @@ run (void *cls, } reserve_closures = GNUNET_CONTAINER_multihashmap_create (1024, GNUNET_NO); + out_map = GNUNET_CONTAINER_multihashmap_create (1024, + true); if (GNUNET_OK != TALER_EXCHANGEDB_load_accounts (TALER_ARL_cfg, TALER_EXCHANGEDB_ALO_DEBIT @@ -2102,10 +1900,6 @@ main (int argc, not do this, the linker may "optimize" libtalerutil away and skip #TALER_OS_init(), which we do need */ (void) TALER_project_data_default (); - if (GNUNET_OK != - GNUNET_STRINGS_get_utf8_args (argc, argv, - &argc, &argv)) - return EXIT_INVALIDARGUMENT; ret = GNUNET_PROGRAM_run ( argc, argv, @@ -2115,7 +1909,6 @@ main (int argc, options, &run, NULL); - GNUNET_free_nz ((void *) argv); if (GNUNET_SYSERR == ret) return EXIT_INVALIDARGUMENT; if (GNUNET_NO == ret) diff --git a/src/auditor/test-auditor.sh b/src/auditor/test-auditor.sh index 65b463e39..d83d1604f 100755 --- a/src/auditor/test-auditor.sh +++ b/src/auditor/test-auditor.sh @@ -1,7 +1,7 @@ #!/bin/bash # # This file is part of TALER -# Copyright (C) 2014-2023 Taler Systems SA +# Copyright (C) 2014-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 @@ -51,18 +51,13 @@ export TALER_AUDITOR_SALT="64S36D1N6RVKGC9J6CT3ADHQ70RK4CSM6MV3EE1H68SK8D9P6WW32 # VALGRIND=valgrind VALGRIND="" -# Number of seconds to let libeuifn background -# tasks apply a cycle of payment submission and -# history request. -LIBEUFIN_SETTLE_TIME=1 - . setup.sh # Cleanup exchange and libeufin between runs. function cleanup() { - if [ ! -z "${EPID:-}" ] + if [ -n "${EPID:-}" ] then echo -n "Stopping exchange $EPID..." kill -TERM "$EPID" @@ -70,23 +65,25 @@ function cleanup() echo "DONE" unset EPID fi - stop_libeufin + stop_libeufin &> /dev/null } # Cleanup to run whenever we exit function exit_cleanup() { - echo "Running exit-cleanup" - if [ ! -z "${POSTGRES_PATH:-}" ] + jobs + if [ -n "${POSTGRES_PATH:-}" ] then - echo "Stopping Postgres at ${POSTGRES_PATH}" + echo -n "Stopping Postgres at ${POSTGRES_PATH} ..." "${POSTGRES_PATH}/pg_ctl" \ -D "$TMPDIR" \ - -l /dev/null \ + --log="${MY_TMP_DIR}/pg_ctl.log" \ stop \ - &> /dev/null \ + &> ${MY_TMP_DIR}/pg_ctl.out \ || true + echo "DONE" fi + echo -n "Running exit-cleanup ..." cleanup for n in $(jobs -p) do @@ -100,13 +97,7 @@ function exit_cleanup() trap exit_cleanup EXIT -# Operations to run before the actual audit -function pre_audit () { - # Launch bank - echo -n "Launching libeufin-bank" - export CONF - export MY_TMP_DIR - launch_libeufin +function await_bank () { for n in $(seq 1 80) do echo -n "." @@ -123,7 +114,18 @@ function pre_audit () { then exit_skip "Failed to launch libeufin-bank" fi + } + +# Operations to run before the actual audit +function pre_audit () { + # Launch bank + echo -n "Launching libeufin-bank" + export CONF + export MY_TMP_DIR + launch_libeufin + await_bank echo " DONE" + if [ "${1:-no}" = "aggregator" ] then echo -n "Running exchange aggregator ..." @@ -229,24 +231,42 @@ function audit_only () { 2> "${MY_TMP_DIR}/test-audit-reserves-inc.err" \ || exit_fail "incremental reserves audit failed (see ${MY_TMP_DIR}/test-audit-reserves-inc.*)" echo -n "." - #$VALGRIND taler-helper-auditor-wire \ - # -i \ - # -L DEBUG \ - # -c "$CONF" \ - # -t \ - # > "${MY_TMP_DIR}/test-audit-wire.out" \ - # 2> "${MY_TMP_DIR}/test-audit-wire.err" \ - # || exit_fail "wire audit failed (see ${MY_TMP_DIR}/test-audit-wire.*)" - #echo -n "." - #$VALGRIND taler-helper-auditor-wire \ - # -i \ - # -L DEBUG \ - # -c "$CONF" \ - # -t \ - # > "${MY_TMP_DIR}/test-audit-wire-inc.out" \ - # 2> "${MY_TMP_DIR}/test-audit-wire-inc.err" \ - # || exit_fail "wire audit inc failed (see ${MY_TMP_DIR}/test-audit-wire-inc.*)" - #echo -n "." + $VALGRIND taler-helper-auditor-wire-credit \ + -i \ + -L DEBUG \ + -c "$CONF" \ + -t \ + > "${MY_TMP_DIR}/test-audit-wire-credit.out" \ + 2> "${MY_TMP_DIR}/test-audit-wire-credit.err" \ + || exit_fail "wire credit audit failed (see ${MY_TMP_DIR}/test-audit-wire-credit.*)" + echo -n "." + $VALGRIND taler-helper-auditor-wire-credit \ + -i \ + -L DEBUG \ + -c "$CONF" \ + -t \ + > "${MY_TMP_DIR}/test-audit-wire-credit-inc.out" \ + 2> "${MY_TMP_DIR}/test-audit-wire-credit-inc.err" \ + || exit_fail "wire credit audit inc failed (see ${MY_TMP_DIR}/test-audit-wire-credit-inc.*)" + echo -n "." + $VALGRIND taler-helper-auditor-wire-debit \ + -i \ + -L DEBUG \ + -c "$CONF" \ + -t \ + > "${MY_TMP_DIR}/test-audit-wire-debit.out" \ + 2> "${MY_TMP_DIR}/test-audit-wire-debit.err" \ + || exit_fail "wire debit audit failed (see ${MY_TMP_DIR}/test-audit-wire-debit.*)" + echo -n "." + $VALGRIND taler-helper-auditor-wire-debit \ + -i \ + -L DEBUG \ + -c "$CONF" \ + -t \ + > "${MY_TMP_DIR}/test-audit-wire-debit-inc.out" \ + 2> "${MY_TMP_DIR}/test-audit-wire-debit-inc.err" \ + || exit_fail "wire debit audit inc failed (see ${MY_TMP_DIR}/test-audit-wire-debit-inc.*)" + echo -n "." $VALGRIND taler-helper-auditor-purses \ -i \ -L DEBUG \ @@ -265,6 +285,24 @@ function audit_only () { 2> "${MY_TMP_DIR}/test-audit-purses-inc.err" \ || exit_fail "audit purses inc failed" echo -n "." + $VALGRIND taler-helper-auditor-transfer \ + -i \ + -L DEBUG \ + -c "$CONF" \ + -t \ + > "${MY_TMP_DIR}/test-audit-transfer.out" \ + 2> "${MY_TMP_DIR}/test-audit-transfer.err" \ + || exit_fail "audit transfer failed" + echo -n "." + $VALGRIND taler-helper-auditor-transfer \ + -i \ + -L DEBUG \ + -c "$CONF" \ + -t \ + > "${MY_TMP_DIR}/test-audit-transfer-inc.out" \ + 2> "${MY_TMP_DIR}/test-audit-transfer-inc.err" \ + || exit_fail "audit transfer inc failed" + echo -n "." echo " DONE" } @@ -277,7 +315,6 @@ function post_audit () { -g \ || exit_fail "exchange DB GC failed" cleanup - echo " DONE" } @@ -297,14 +334,14 @@ function run_audit () { 2> "${MY_TMP_DIR}/exchange-httpd-drain.err" & EPID=$! - # Wait for all services to be available + # Wait for exchange service to be available for n in $(seq 1 50) do echo -n "." sleep 0.1 OK=0 # exchange - wget "http://localhost:8081/seed" \ + wget "http://localhost:8081/config" \ -o /dev/null \ -O /dev/null \ >/dev/null \ @@ -321,7 +358,7 @@ function run_audit () { -L DEBUG \ -c "${CONF}" \ drain TESTKUDOS:0.1 \ - exchange-account-1 payto://iban/SANDBOXX/DE360679?receiver-name=Exchange+Drain \ + exchange-account-1 payto://iban/DE474361?receiver-name=Merchant43 \ upload \ 2> "${MY_TMP_DIR}/taler-exchange-offline-drain.log" \ || exit_fail "offline draining failed" @@ -350,12 +387,23 @@ function run_audit () { } +function stop_auditor_httpd() { + if [ -n "${APID:-}" ] + then + echo -n "Stopping auditor $APID..." + kill -TERM "$APID" + wait "$APID" || true + echo "DONE" + unset APID + fi +} + + # Do a full reload of the (original) database function full_reload() { echo -n "Doing full reload of the database (loading ${BASEDB}.sql into $DB at $PGHOST)... " - dropdb -f "$DB" 2> /dev/null || true - echo "/n here is a problem " + dropdb -f "$DB" &>> ${MY_TMP_DIR}/drop.log || true createdb -T template0 "$DB" \ || exit_skip "could not create database $DB (at $PGHOST)" # Import pre-generated database, -q(ietly) using single (-1) transaction @@ -363,54 +411,44 @@ function full_reload() -q \ -1 \ -f "${BASEDB}.sql" \ - > /dev/null \ + &>> ${MY_TMP_DIR}/postgresql-reload.log \ || exit_skip "Failed to load database $DB from ${BASEDB}.sql" echo "DONE" # Technically, this call shouldn't be needed as libeufin should already be stopped here... stop_libeufin + stop_auditor_httpd } function run_auditor_httpd() { echo -n "Starting auditor..." - taler-auditor-httpd \ - -c "${CONF}" \ - -L INFO \ - 2> "${MY_TMP_DIR}/auditor-httpd-drain.err" & - APID=$! - - # Wait for all services to be available - for n in $(seq 1 50) - do - echo -n "." - sleep 0.1 - OK=0 - # exchange - wget "http://localhost:8083/seed" \ - -o /dev/null \ - -O /dev/null \ - >/dev/null \ - || continue - OK=1 - break - done - echo "... DONE." - export CONF + $VALGRIND taler-auditor-httpd \ + -c "${CONF}" \ + -L INFO \ + 2> "${MY_TMP_DIR}/auditor-httpd.err" & + APID=$! + + # Wait for auditor service to be available + for n in $(seq 1 50) + do + echo -n "." + sleep 0.2 + OK=0 + # auditor + wget "http://localhost:8083/config" \ + -o /dev/null \ + -O /dev/null \ + >/dev/null \ + || continue + OK=1 + break + done + echo "... DONE." } -function stop_auditor_httpd() { -if [ ! -z "${APID:-}" ] - then - echo -n "Stopping auditor $APID..." - kill -TERM "$APID" - wait "$APID" || true - echo "DONE" - unset APID - fi -} function check_auditor_running() { ARUNSTATUS=$(curl -Is http://localhost:8083/config | head -1) - if [ ! -z "${ARUNSTATUS:-}" ] + if [ -n "${ARUNSTATUS:-}" ] then echo "Auditor running" else @@ -421,149 +459,202 @@ function check_auditor_running() { } function call_endpoint() { - if [ ! -z ${2+x} ] - then - curl -s -H "Accept: application/json" -H "Authorization: Bearer ${TALER_AUDITOR_TOKEN}" -o "${MY_TMP_DIR}/${2}.json" "localhost:8083/monitoring/${1}?limit=50&balance_key=${2}" - else - curl -s -H "Accept: application/json" -H "Authorization: Bearer ${TALER_AUDITOR_TOKEN}" -o "${MY_TMP_DIR}/${1}.json" "localhost:8083/monitoring/${1}?limit=50" - fi + if [ -n "${2+x}" ] + then + curl -s -H "Accept: application/json" -H "Authorization: Bearer ${TALER_AUDITOR_TOKEN}" -o "${MY_TMP_DIR}/${2}.json" "localhost:8083/monitoring/${1}?limit=50&balance_key=${2}" + echo -n "CD... " + else + curl -s -H "Accept: application/json" -H "Authorization: Bearer ${TALER_AUDITOR_TOKEN}" -o "${MY_TMP_DIR}/${1}.json" "localhost:8083/monitoring/${1}?limit=50" + echo -n "CD... " + fi } -function test_0() { - - echo "===========0: normal run with aggregator===========" - run_audit aggregator - check_auditor_running - echo "Checking output" - - # if an emergency was detected, that is a bug and we should fail - echo -n "Test for emergencies... " - call_endpoint "emergency" - jq -e .emergency[0] < ${MY_TMP_DIR}/emergency.json > /dev/null && exit_fail "Unexpected emergency detected in ordinary run" || echo PASS - echo -n "Test for deposit confirmation emergencies... " - call_endpoint "deposit-confirmation" - jq -e .deposit_confirmation[0] < ${MY_TMP_DIR}/deposit-confirmation.json > /dev/null && exit_fail "Unexpected deposit confirmation inconsistency detected" || echo PASS - echo -n "Test for emergencies by count... " - call_endpoint "emergency-by-count" - jq -e .emergency_by_count[0] < ${MY_TMP_DIR}/emergency-by-count.json > /dev/null && exit_fail "Unexpected emergency by count detected in ordinary run" || echo PASS +function check_balance() { + call_endpoint "balances" "$1" + BAL=$(jq -r .balances[0].balance_value < "${MY_TMP_DIR}/${1}.json") + if [ "$BAL" != "$2" ] + then + exit_fail "$3 (got $BAL, wanted $2)" + fi + echo "PASS" +} - echo -n "Test for wire inconsistencies... " - #jq -e .wire_out_amount_inconsistencies[0] < test-audit-wire.json > /dev/null && exit_fail "Unexpected wire out inconsistency detected in ordinary run" - #jq -e .reserve_in_amount_inconsistencies[0] < test-audit-wire.json > /dev/null && exit_fail "Unexpected reserve in inconsistency detected in ordinary run" - #jq -e .misattribution_inconsistencies[0] < test-audit-wire.json > /dev/null && exit_fail "Unexpected misattribution inconsistency detected in ordinary run" - #jq -e .row_inconsistencies[0] < test-audit-wire.json > /dev/null && exit_fail "Unexpected row inconsistency detected in ordinary run" - call_endpoint "denomination-key-validity-withdraw-inconsistency" - jq -e .denomination_key_validity_withdraw_inconsistency[0] < ${MY_TMP_DIR}/denomination-key-validity-withdraw-inconsistency.json > /dev/null && exit_fail "Unexpected denomination key withdraw inconsistency detected in ordinary run" - #jq -e .row_minor_inconsistencies[0] < test-audit-wire.json > /dev/null && exit_fail "Unexpected minor row inconsistency detected in ordinary run" - #jq -e .lag_details[0] < test-audit-wire.json > /dev/null && exit_fail "Unexpected lag detected in ordinary run" - #jq -e .wire_format_inconsistencies[0] < test-audit-wire.json > /dev/null && exit_fail "Unexpected wire format inconsistencies detected in ordinary run" +function check_not_balance() { + call_endpoint "balances" "$1" + BAL=$(jq -r .balances[0].balance_value < "${MY_TMP_DIR}/${1}.json") + if [ "$BAL" = "$2" ] + then + exit_fail "$3 (got $BAL, wanted NOT $2)" + fi + echo "PASS" +} - # TODO: check operation balances are correct (once we have all transaction types and wallet is deterministic) - # TODO: check revenue summaries are correct (once we have all transaction types and wallet is deterministic) - echo PASS - call_endpoint "balances" - call_endpoint "balances" "coin_irregular_loss" - call_endpoint "balances" "aggregator_total_bad_sig_loss" - call_endpoint "balances" "reserves_total_bad_sig_loss" - call_endpoint "amount-arithmetic-inconsistency" +function check_report() { + call_endpoint "$1" + NAME=$(echo "$1" | tr '-' '_') + # shellcheck disable=SC2086 + VAL=$(jq -r .\"${NAME}\"[0].\"$2\" < "${MY_TMP_DIR}/${1}.json") + if [ "$VAL" != "$3" ] + then + exit_fail "$1::$2 (got $VAL, wanted $3)" + fi + echo "PASS" +} - #${MY_TMP_DIR}/test-audit-bad-sig-losses.json +function check_no_report() { + call_endpoint "$1" + NAME=$(echo "$1" | tr '-' '_') + # shellcheck disable=SC2086 + jq -e .\"${NAME}\"[0] \ + < "${MY_TMP_DIR}/${1}.json" \ + > /dev/null \ + && exit_fail "Wanted empty report for $1, but got incidents" + echo "PASS" +} - LOSS=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/aggregator_total_bad_sig_loss.json) - if [ "$LOSS" != "TESTKUDOS:0" ] +function check_report_neg() { + call_endpoint "$1" + NAME=$(echo "$1" | tr '-' '_') + # shellcheck disable=SC2086 + VAL=$(jq -r .\"${NAME}\"[0].\"$2\" < "${MY_TMP_DIR}/${1}.json") + if [ "$VAL" == "$3" ] then - exit_fail "Wrong total bad sig loss from aggregation, got unexpected loss of $LOSS" + exit_fail "$1::$2 (got $VAL, wanted $3)" fi - LOSS=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/coin_irregular_loss.json) - if [ "$LOSS" != "TESTKUDOS:0" ] + echo "PASS" +} + +function check_row() { + call_endpoint "$1" + NAME=$(echo "$1" | tr '-' '_') + if [ -n "${3+x}" ] then - exit_fail "Wrong total bad sig loss from coins, got unexpected loss of $LOSS" + RID="$2" + WANT="$3" + else + RID="row_id" + WANT="$2" fi - LOSS=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/reserves_total_bad_sig_loss.json) - if [ "$LOSS" != "TESTKUDOS:0" ] + # shellcheck disable=SC2086 + ROW=$(jq -r .\"${NAME}\"[0].\"${RID}\" < "${MY_TMP_DIR}/${1}.json") + if [ "$ROW" != "$WANT" ] then - exit_fail "Wrong total bad sig loss from reserves, got unexpected loss of $LOSS" + exit_fail "Row ${1} wrong (got ${ROW}, wanted ${WANT})" fi + echo "PASS" +} - #echo -n "Test for wire amounts... " - #WIRED=$(jq -r .total_wire_in_delta_plus < test-audit-wire.json) - #if [ "$WIRED" != "TESTKUDOS:0" ] - #then - # exit_fail "Expected total wire delta plus wrong, got $WIRED" - #fi - #WIRED=$(jq -r .total_wire_in_delta_minus < test-audit-wire.json) - #if [ "$WIRED" != "TESTKUDOS:0" ] - #then - # exit_fail "Expected total wire delta minus wrong, got $WIRED" - #fi - #WIRED=$(jq -r .total_wire_out_delta_plus < test-audit-wire.json) - #if [ "$WIRED" != "TESTKUDOS:0" ] - #then - # exit_fail "Expected total wire delta plus wrong, got $WIRED" - #fi - #WIRED=$(jq -r .total_wire_out_delta_minus < test-audit-wire.json) - #if [ "$WIRED" != "TESTKUDOS:0" ] - #then - # exit_fail "Expected total wire delta minus wrong, got $WIRED" - #fi - #WIRED=$(jq -r .total_misattribution_in < test-audit-wire.json) - #if [ "$WIRED" != "TESTKUDOS:0" ] - #then - # exit_fail "Expected total misattribution in wrong, got $WIRED" - #fi - #echo "PASS" - call_endpoint "balances" "aggregator_total_arithmetic_delta_plus" - call_endpoint "balances" "aggregator_total_arithmetic_delta_minus" - call_endpoint "balances" "coins_total_arithmetic_delta_plus" - call_endpoint "balances" "coins_total_arithmetic_delta_minus" - call_endpoint "balances" "reserves_total_arithmetic_delta_plus" - call_endpoint "balances" "reserves_total_arithmetic_delta_minus" +function test_0() { - echo -n "Checking for unexpected arithmetic differences " - LOSS=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/aggregator_total_arithmetic_delta_plus.json) - if [ "$LOSS" != "TESTKUDOS:0" ] - then - exit_fail "Wrong arithmetic delta from aggregations, got unexpected plus of $LOSS" - fi - LOSS=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/aggregator_total_arithmetic_delta_minus.json) - if [ "$LOSS" != "TESTKUDOS:0" ] - then - exit_fail "Wrong arithmetic delta from aggregation, got unexpected minus of $LOSS" - fi - LOSS=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/coins_total_arithmetic_delta_plus.json) - if [ "$LOSS" != "TESTKUDOS:0" ] - then - exit_fail "Wrong arithmetic delta from coins, got unexpected plus of $LOSS" - fi - LOSS=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/coins_total_arithmetic_delta_minus.json) - if [ "$LOSS" != "TESTKUDOS:0" ] - then - exit_fail "Wrong arithmetic delta from coins, got unexpected minus of $LOSS" - fi - LOSS=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/reserves_total_arithmetic_delta_plus.json) - if [ "$LOSS" != "TESTKUDOS:0" ] - then - exit_fail "Wrong arithmetic delta from reserves, got unexpected plus of $LOSS" - fi - LOSS=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/reserves_total_arithmetic_delta_minus.json) - if [ "$LOSS" != "TESTKUDOS:0" ] - then - exit_fail "Wrong arithmetic delta from reserves, got unexpected minus of $LOSS" - fi + echo "===========0: normal run with aggregator===========" + run_audit aggregator + check_auditor_running - jq -e .amount_arithmetic_inconsistency[0] < ${MY_TMP_DIR}/test-audit-aggregation.out > /dev/null && exit_fail "Unexpected arithmetic inconsistencies from aggregations detected in ordinary run" - jq -e .amount_arithmetic_inconsistency[0] < ${MY_TMP_DIR}/test-audit-coins.out > /dev/null && exit_fail "Unexpected arithmetic inconsistencies from coins detected in ordinary run" - jq -e .amount_arithmetic_inconsistency[0] < ${MY_TMP_DIR}/test-audit-reserves.out > /dev/null && exit_fail "Unexpected arithmetic inconsistencies from reserves detected in ordinary run" - echo "PASS" + echo "Checking output" + + # if an emergency was detected, that is a bug and we should fail + echo -n "Test for emergencies... " + check_no_report "emergency" + echo -n "Test for emergencies by count... " + check_no_report "emergency-by-count" + echo -n "Test for wire inconsistencies... " + check_no_report "denomination-key-validity-withdraw-inconsistency" + echo -n "Test for deposit confirmation problems... " + check_no_report "deposit-confirmation" + + # Just to test the endpoint and for logging ... + call_endpoint "balances" + + echo -n "Testing bad sig loss balance... " + check_balance \ + "aggregation_total_bad_sig_loss" \ + "TESTKUDOS:0" \ + "Wrong total bad sig loss from aggregation, got unexpected loss" + + echo -n "Testing coin irregular loss balances... " + check_balance \ + "coin_irregular_loss" \ + "TESTKUDOS:0" \ + "Wrong total bad sig loss from coins" + + echo -n "Testing reserves bad sig loss balances... " + check_balance \ + "reserves_total_bad_sig_loss" \ + "TESTKUDOS:0" \ + "Wrong total bad sig loss from reserves" + + echo -n "Test for aggregation wire out delta plus... " + check_balance \ + "aggregation_total_wire_out_delta_plus" \ + "TESTKUDOS:0" \ + "Expected total wire out delta plus wrong" + + echo -n "Test for aggregation wire out delta minus... " + check_balance \ + "aggregation_total_wire_out_delta_minus" \ + "TESTKUDOS:0" \ + "Expected total wire out delta minus wrong" + + echo -n "Test for bad incoming delta plus... " + check_balance \ + "total_bad_amount_in_plus" \ + "TESTKUDOS:0" \ + "Expected total wire in delta plus wrong" + + echo -n "Test for bad incoming delta minus... " + check_balance \ + "total_bad_amount_in_minus" \ + "TESTKUDOS:0" \ + "Expected total wire in delta minus wrong" + + echo -n "Test for misattribution amounts... " + check_balance \ + "total_misattribution_in" \ + "TESTKUDOS:0" \ + "Expected total misattribution in wrong" + + echo -n "Checking for unexpected aggregation delta plus differences... " + check_balance \ + "aggregation_total_arithmetic_delta_plus" \ + "TESTKUDOS:0" \ + "Wrong arithmetic delta plus from aggregations" + + echo -n "Checking for unexpected aggregation delta minus differences... " + check_balance \ + "aggregation_total_arithmetic_delta_minus" \ + "TESTKUDOS:0" \ + "Wrong arithmetic delta minus from aggregations" + + echo -n "Checking for unexpected coin delta plus differences... " + check_balance \ + "coins_total_arithmetic_delta_plus" \ + "TESTKUDOS:0" \ + "Wrong arithmetic delta plus from coins" + + echo -n "Checking for unexpected coin delta minus differences... " + check_balance \ + "coins_total_arithmetic_delta_minus" \ + "TESTKUDOS:0" \ + "Wrong arithmetic delta minus from coins" + + echo -n "Checking for unexpected reserves delta plus... " + check_balance \ + "reserves_total_arithmetic_delta_plus" \ + "TESTKUDOS:0" \ + "Wrong arithmetic delta plus from reserves" + + echo -n "Checking for unexpected reserves delta minus... " + check_balance \ + "reserves_total_arithmetic_delta_minus" \ + "TESTKUDOS:0" \ + "Wrong arithmetic delta minus from reserves" echo -n "Checking for unexpected wire out differences " - call_endpoint "wire-out-inconsistency" - jq -e .wire_out_inconsistency[0] < "${MY_TMP_DIR}/wire-out-inconsistency.json" > /dev/null && exit_fail "Unexpected wire out inconsistencies detected in ordinary run" - echo "PASS" + check_no_report "wire-out-inconsistency" # cannot easily undo aggregator, hence full reload full_reload @@ -582,96 +673,42 @@ function test_1() { echo "Checking output" # if an emergency was detected, that is a bug and we should fail - call_endpoint "emergency" - call_endpoint "emergency-by-count" + call_endpoint "balances" echo -n "Test for emergencies... " - jq -e .emergency[0] \ - < ${MY_TMP_DIR}/emergency.json \ - > /dev/null && exit_fail "Unexpected emergency detected in ordinary run" || echo PASS - + check_no_report "emergency" echo -n "Test for emergencies by count... " - jq -e .emergency_by_count[0] \ - < ${MY_TMP_DIR}/emergency-by-count.json \ - > /dev/null && exit_fail "Unexpected emergency by count detected in ordinary run" || echo PASS - - #echo -n "Test for wire inconsistencies... " - #jq -e .wire_out_amount_inconsistencies[0] \ - # < test-audit-wire.json \ - # > /dev/null \ - # && exit_fail "Unexpected wire out inconsistency detected in ordinary run" - #jq -e .reserve_in_amount_inconsistencies[0] \ - # < test-audit-wire.json \ - # > /dev/null \ - # && exit_fail "Unexpected reserve in inconsistency detected in ordinary run" - #jq -e .misattribution_inconsistencies[0] \ - # < test-audit-wire.json \ - # > /dev/null \ - # && exit_fail "Unexpected misattribution inconsistency detected in ordinary run" - #jq -e .row_inconsistencies[0] \ - # < test-audit-wire.json \ - # > /dev/null \ - # && exit_fail "Unexpected row inconsistency detected in ordinary run" - #jq -e .row_minor_inconsistencies[0] \ - # < test-audit-wire.json \ - # > /dev/null \ - # && exit_fail "Unexpected minor row inconsistency detected in ordinary run" - #jq -e .wire_format_inconsistencies[0] \ - # < test-audit-wire.json \ - # > /dev/null \ - # && exit_fail "Unexpected wire format inconsistencies detected in ordinary run" + check_no_report "emergency-by-count" + echo -n "Test for wire inconsistencies... " + check_no_report "denomination-key-validity-withdraw-inconsistency" # TODO: check operation balances are correct (once we have all transaction types and wallet is deterministic) # TODO: check revenue summaries are correct (once we have all transaction types and wallet is deterministic) - echo "PASS" - echo -n "Check for lag detection... " - # Check wire transfer lag reported (no aggregator!) - # NOTE: This test is EXPECTED to fail for ~1h after - # re-generating the test database as we do not - # report lag of less than 1h (see GRACE_PERIOD in - # taler-helper-auditor-wire.c) - #jq -e .lag_details[0] \ - # < test-audit-wire.json \ - # > /dev/null \ - # || exit_fail "Lag not detected in run without aggregator" -# - #LAG=$(jq -r .total_amount_lag < test-audit-wire.json) - #if [ "$LAG" = "TESTKUDOS:0" ] - #then - # exit_fail "Expected total lag to be non-zero" - #fi - echo "PASS" -# -# - #echo -n "Test for wire amounts... " - #WIRED=$(jq -r .total_wire_in_delta_plus < test-audit-wire.json) - #if [ "$WIRED" != "TESTKUDOS:0" ] - #then - # exit_fail "Expected total wire delta plus wrong, got $WIRED" - #fi - #WIRED=$(jq -r .total_wire_in_delta_minus < test-audit-wire.json) - #if [ "$WIRED" != "TESTKUDOS:0" ] - #then - # exit_fail "Expected total wire delta minus wrong, got $WIRED" - #fi - #WIRED=$(jq -r .total_wire_out_delta_plus < test-audit-wire.json) - #if [ "$WIRED" != "TESTKUDOS:0" ] - #then - # exit_fail "Expected total wire delta plus wrong, got $WIRED" - #fi - #WIRED=$(jq -r .total_wire_out_delta_minus < test-audit-wire.json) - #if [ "$WIRED" != "TESTKUDOS:0" ] - #then - # exit_fail "Expected total wire delta minus wrong, got $WIRED" - #fi - #WIRED=$(jq -r .total_misattribution_in < test-audit-wire.json) - #if [ "$WIRED" != "TESTKUDOS:0" ] - #then - # exit_fail "Expected total misattribution in wrong, got $WIRED" - #fi + check_not_balance \ + "total_amount_lag" \ + "TESTKUDOS:0" \ + "Failed to detect lag" + + echo -n "Test for bad incoming delta plus... " + check_balance \ + "total_bad_amount_in_plus" \ + "TESTKUDOS:0" \ + "Expected total wire in delta plus wrong" + + echo -n "Test for bad incoming delta minus... " + check_balance \ + "total_bad_amount_in_minus" \ + "TESTKUDOS:0" \ + "Expected total wire in delta minus wrong" + + echo -n "Test for misattribution amounts... " + check_balance \ + "total_misattribution_in" \ + "TESTKUDOS:0" \ + "Expected total misattribution in wrong" # Database was unmodified, no need to undo } @@ -680,45 +717,41 @@ function test_1() { function test_2() { echo "===========2: reserves_in inconsistency ===========" + echo -n "Modifying database: " echo "UPDATE exchange.reserves_in SET credit.val=5 WHERE reserve_in_serial_id=1" \ | psql -At "$DB" run_audit check_auditor_running - #echo -n "Testing inconsistency detection... " - #ROW=$(jq .reserve_in_amount_inconsistencies[0].row < test-audit-wire.json) - #if [ "$ROW" != 1 ] - #then - # exit_fail "Row $ROW is wrong" - #fi - #WIRED=$(jq -r .reserve_in_amount_inconsistencies[0].amount_wired < test-audit-wire.json) - #if [ "$WIRED" != "TESTKUDOS:10" ] - #then - # exit_fail "Amount wrong" - #fi - #EXPECTED=$(jq -r .reserve_in_amount_inconsistencies[0].amount_exchange_expected < test-audit-wire.json) - #if [ "$EXPECTED" != "TESTKUDOS:5" ] - #then - # exit_fail "Expected amount wrong" - #fi -# - #WIRED=$(jq -r .total_wire_in_delta_minus < test-audit-wire.json) - #if [ "$WIRED" != "TESTKUDOS:0" ] - #then - # exit_fail "Wrong total wire_in_delta_minus, got $WIRED" - #fi - #DELTA=$(jq -r .total_wire_in_delta_plus < test-audit-wire.json) - #if [ "$DELTA" != "TESTKUDOS:5" ] - #then - # exit_fail "Expected total wire delta plus wrong, got $DELTA" - #fi - #echo "PASS" + echo -n "Testing inconsistency detection ... " + check_report \ + "reserve-in-inconsistency" \ + "row_id" 1 + echo -n "Testing inconsistency detection amount wired ... " + check_report \ + "reserve-in-inconsistency" \ + "amount_wired" "TESTKUDOS:10" + echo -n "Testing inconsistency detection amount expected ... " + check_report \ + "reserve-in-inconsistency" \ + "amount_exchange_expected" "TESTKUDOS:5" - # Undo database modification + call_endpoint "balances" + echo -n "Checking wire credit balance minus ... " + check_balance \ + "total_bad_amount_in_minus" \ + "TESTKUDOS:0" \ + "Wrong total_bad_amount_in_minus" + echo -n "Checking wire credit balance plus ... " + check_balance \ + "total_bad_amount_in_plus" \ + "TESTKUDOS:5" \ + "Expected total_bad_amount_in_plus wrong" + + echo -n "Undoing database modification " echo "UPDATE exchange.reserves_in SET credit.val=10 WHERE reserve_in_serial_id=1" \ | psql -Aqt "$DB" - stop_auditor_httpd full_reload cleanup } @@ -735,62 +768,46 @@ function test_3() { run_audit check_auditor_running - call_endpoint "reserve-balance-summary-wrong-inconsistency" - EXPECTED=$(jq -e .reserve_balance_summary_wrong_inconsistency[0].auditor_amount \ - < ${MY_TMP_DIR}/reserve-balance-summary-wrong-inconsistency.json) - if [ $EXPECTED != '"TESTKUDOS:5.01"' ] - then - exit_fail "Expected reserve balance summary amount wrong, got $EXPECTED (auditor)" - fi - - EXPECTED=$(jq -e .reserve_balance_summary_wrong_inconsistency[0].exchange_amount \ - < ${MY_TMP_DIR}/reserve-balance-summary-wrong-inconsistency.json) - if [ $EXPECTED != '"TESTKUDOS:0.01"' ] - then - exit_fail "Expected reserve balance summary amount wrong, got $EXPECTED (exchange)" - fi - - #TODO: we receive 22.96 instead of 0 - check what it should be - #call_endpoint "balances" "reserves_reserve_loss" - #WIRED=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/reserves_reserve_loss.json) - #if [ "$WIRED" != "TESTKUDOS:0" ] - #then - # exit_fail "Wrong total loss from insufficient balance, got $WIRED" - #fi - #TODO: fix helper wire - #ROW=$(jq -e .reserve_in_amount_inconsistencies[0].row < test-audit-wire.json) - #if [ "$ROW" != 1 ] - #then - # exit_fail "Row wrong, got $ROW" - #fi + echo "Checking reserve balance summary inconsistency detection ..." + check_report \ + "reserve-balance-summary-wrong-inconsistency" \ + "auditor_amount" "TESTKUDOS:5.01" + check_report \ + "reserve-balance-summary-wrong-inconsistency" \ + "exchange_amount" "TESTKUDOS:0.01" - #WIRED=$(jq -r .reserve_in_amount_inconsistencies[0].amount_exchange_expected < test-audit-wire.json) - #if [ "$WIRED" != "TESTKUDOS:15" ] - #then - # exit_fail "Wrong amount_exchange_expected, got $WIRED" - #fi - - #WIRED=$(jq -r .reserve_in_amount_inconsistencies[0].amount_wired < test-audit-wire.json) - #if [ "$WIRED" != "TESTKUDOS:10" ] - #then - # exit_fail "Wrong amount_wired, got $WIRED" - #fi - - #WIRED=$(jq -r .total_wire_in_delta_minus < test-audit-wire.json) - #if [ "$WIRED" != "TESTKUDOS:5" ] - #then - # exit_fail "Wrong total wire_in_delta_minus, got $WIRED" - #fi - - #WIRED=$(jq -r .total_wire_in_delta_plus < test-audit-wire.json) - #if [ "$WIRED" != "TESTKUDOS:0" ] - #then - # exit_fail "Wrong total wire_in_delta_plus, got $WIRED" - #fi + call_endpoint "balances" + check_balance \ + "reserves_reserve_loss" \ + "TESTKUDOS:0" \ + "Wrong total loss from insufficient balance" + + echo -n "Testing inconsistency detection ... " + check_report \ + "reserve-in-inconsistency" \ + "row_id" 1 + echo -n "Testing inconsistency detection amount wired ... " + check_report \ + "reserve-in-inconsistency" \ + "amount_wired" "TESTKUDOS:10" + echo -n "Testing inconsistency detection amount expected ... " + check_report \ + "reserve-in-inconsistency" \ + "amount_exchange_expected" "TESTKUDOS:15" + + echo -n "Checking wire credit balance minus ... " + check_balance \ + "total_bad_amount_in_minus" \ + "TESTKUDOS:5" \ + "Wrong total_bad_amount_in_minus" + echo -n "Checking wire credit balance plus ... " + check_balance \ + "total_bad_amount_in_plus" \ + "TESTKUDOS:0" \ + "Wrong total_bad_amount_in_plus" # Undo database modification echo "UPDATE exchange.reserves_in SET credit.val=10 WHERE reserve_in_serial_id=1" | psql -Aqt "$DB" - stop_auditor_httpd full_reload cleanup } @@ -799,68 +816,44 @@ function test_3() { # Check for incoming wire transfer amount given being # lower than what exchange claims to have received. function test_4() { -# TODO : may need to be restructured, as db seems to have done echo "===========4: deposit wire target wrong=================" -# # Original target bank account was 43, changing to 44 -# # TODO: ask grothoff check if I correctly chose table coin_deposit -# -# SERIALE=$(echo "SELECT coin_deposit_serial_id FROM exchange.coin_deposits WHERE (amount_with_fee).val=3 ORDER BY coin_deposit_serial_id LIMIT 1;" | psql "$DB" -Aqt) -# -# #SERIAL=$(echo "SELECT coin_deposit_serial_id FROM exchange.coin_deposits WHERE (amount_with_fee).val=3 AND (amount_with_fee).frac=0 ORDER BY coin_deposit_serial_id LIMIT 1;" | psql "$DB" -Aqt) -# echo $SERIALE -# OLD_WIRE_ID=$(echo "SELECT coin_sig FROM exchange.coin_deposits WHERE coin_deposit_serial_id=${SERIALE};" | psql "$DB" -Aqt) -# #OLD_WIRE_ID=$(echo "SELECT wire_target_h_payto FROM exchange.deposits WHERE deposit_serial_id=${SERIAL};" | psql "$DB" -Aqt) -## shellcheck disable=SC2028 -# echo "INSERT INTO exchange.wire_targets (payto_uri, wire_target_h_payto) VALUES ('payto://x-taler-bank/localhost/testuser-xxlargtp', '\x1e8f31936b3cee8f8afd3aac9e38b5db42d45b721ffc4eb1e5b9ddaf1565660b');" \ -# | psql "$DB" \ -# -Aqt \ -# > /dev/null -## shellcheck disable=SC2028 -# #echo "UPDATE exchange.deposits SET wire_target_h_payto='\x1e8f31936b3cee8f8afd3aac9e38b5db42d45b721ffc4eb1e5b9ddaf1565660b' WHERE deposit_serial_id=${SERIAL}" \ -# # | psql -Aqt "$DB" -# echo "UPDATE exchange.coin_deposits SET coin_sig='\x1e8f31936b3cee8f8afd3aac9e38b5db42d45b721ffc4eb1e5b9ddaf1565660b' WHERE coin_deposit_serial_id=${SERIALE}" \ -# | psql -Aqt "$DB" -# -# run_audit -# check_auditor_running -# -# echo -n "Testing inconsistency detection... " -# -# call_endpoint "bad-sig-losses" -# jq -e .bad_sig_losses[0] < ${MY_TMP_DIR}/bad-sig-losses.json > /dev/null || exit_fail "Bad signature not detected" -# -# ROW=$(jq -e .bad_sig_losses[0].row < ${MY_TMP_DIR}/bad-sig-losses.json) -# if [ $ROW != "${SERIALE}" ] -# then -# exit_fail "Row wrong, got $ROW" -# fi -# -# LOSS=$(jq -r .bad_sig_losses[0].loss < ${MY_TMP_DIR}/bad-sig-losses.json) -# if [ $LOSS != '"TESTKUDOS:3"' ] -# then -# exit_fail "Wrong deposit bad signature loss, got $LOSS" -# fi -# -# OP=$(jq -r .bad_sig_losses[0].operation < ${MY_TMP_DIR}/bad-sig-losses.json) -# if [ $OP != "deposit" ] -# then -# exit_fail "Wrong operation, got $OP" -# fi -# -# #LOSS=$(jq -r .irregular_loss < test-audit-coins.json) -# #if [ "$LOSS" != "TESTKUDOS:3" ] -# #then -# # exit_fail "Wrong total bad sig loss, got $LOSS" -# #fi -# -# echo PASS -# # Undo: -# #echo "UPDATE exchange.deposits SET wire_target_h_payto='$OLD_WIRE_ID' WHERE deposit_serial_id=${SERIAL}" | psql -Aqt "$DB" -# echo "UPDATE exchange.deposits SET coin_sig='$OLD_WIRE_ID' WHERE coin_deposit_serial_id=${SERIALE}" | psql -Aqt "$DB" -# -# stop_auditor_httpd -# full_reload -# cleanup + + SERIALE=$(echo "SELECT coin_deposit_serial_id FROM exchange.coin_deposits WHERE (amount_with_fee).val=3 ORDER BY coin_deposit_serial_id LIMIT 1;" | psql "$DB" -Aqt) + OLD_COIN_SIG=$(echo "SELECT coin_sig FROM exchange.coin_deposits WHERE coin_deposit_serial_id=${SERIALE};" | psql "$DB" -Aqt) + echo -n "Manipulating row ${SERIALE} ..." +# shellcheck disable=SC2028 + echo "INSERT INTO exchange.wire_targets (payto_uri, wire_target_h_payto) VALUES ('payto://x-taler-bank/localhost/testuser-xxlargtp', '\x1e8f31936b3cee8f8afd3aac9e38b5db42d45b721ffc4eb1e5b9ddaf1565660b');" \ + | psql -Aqt "$DB" +# shellcheck disable=SC2028 + echo "UPDATE exchange.coin_deposits SET coin_sig='\x0f29b2ebf3cd1ecbb3e1f2a7888872058fc870c28c0065d4a7d457f2fee9eb5ec376958fc52460c8c540e583be10cf67491a6651a62c1bda68051c62dbe9130c' WHERE coin_deposit_serial_id=${SERIALE}" \ + | psql -Aqt "$DB" + echo " DONE" + + run_audit + check_auditor_running + + echo -n "Testing inconsistency detection... " + check_report \ + "bad-sig-losses" \ + "problem_row_id" "${SERIALE}" + echo -n "Testing loss report... " + check_report \ + "bad-sig-losses" \ + "loss" "TESTKUDOS:3.02" + echo -n "Testing loss operation attribution... " + check_report \ + "bad-sig-losses" \ + "operation" "deposit" + echo -n "Testing total coin_irregular_loss balance update... " + check_balance \ + "coin_irregular_loss" \ + "TESTKUDOS:3.02" \ + "wrong total coin_irregular_loss" + # Undo: + echo "UPDATE exchange.coin_deposits SET coin_sig='$OLD_COIN_SIG' WHERE coin_deposit_serial_id=${SERIALE}" | psql -Aqt "$DB" + + full_reload + cleanup } @@ -868,44 +861,39 @@ function test_4() { # (=> bad signature) function test_5() { echo "===========5: deposit contract hash wrong=================" - # TODO: may need to be restructured # Modify h_wire hash, so it is inconsistent with 'wire' -# SERIAL=$(echo "SELECT deposit_serial_id FROM exchange.deposits WHERE amount_with_fee_val=3 AND amount_with_fee_frac=0 ORDER BY deposit_serial_id LIMIT 1" | psql "$DB" -Aqt) -# OLD_H=$(echo "SELECT h_contract_terms FROM exchange.deposits WHERE deposit_serial_id=$SERIAL;" | psql "$DB" -Aqt) -## shellcheck disable=SC2028 -# echo "UPDATE exchange.deposits SET h_contract_terms='\x12bb676444955c98789f219148aa31899d8c354a63330624d3d143222cf3bb8b8e16f69accd5a8773127059b804c1955696bf551dd7be62719870613332aa8d5' WHERE deposit_serial_id=$SERIAL" \ -# | psql -Aqt "$DB" -# -# run_audit -# -# echo -n "Checking bad signature detection... " -# ROW=$(jq -e .bad_sig_losses[0].row < test-audit-coins.json) -# if [ "$ROW" != "$SERIAL" ] -# then -# exit_fail "Row wrong, got $ROW" -# fi -# -# LOSS=$(jq -r .bad_sig_losses[0].loss < test-audit-coins.json) -# if [ "$LOSS" != "TESTKUDOS:3" ] -# then -# exit_fail "Wrong deposit bad signature loss, got $LOSS" -# fi -# -# OP=$(jq -r .bad_sig_losses[0].operation < test-audit-coins.json) -# if [ "$OP" != "deposit" ] -# then -# exit_fail "Wrong operation, got $OP" -# fi -# -# LOSS=$(jq -r .irregular_loss < test-audit-coins.json) -# if [ "$LOSS" != "TESTKUDOS:3" ] -# then -# exit_fail "Wrong total bad sig loss, got $LOSS" -# fi -# echo PASS + CSERIAL=$(echo "SELECT coin_deposit_serial_id FROM exchange.coin_deposits WHERE (amount_with_fee).val=3 ORDER BY coin_deposit_serial_id LIMIT 1;" | psql "$DB" -Aqt) + SERIAL=$(echo "SELECT batch_deposit_serial_id FROM exchange.coin_deposits WHERE (amount_with_fee).val=3 ORDER BY coin_deposit_serial_id LIMIT 1;" | psql "$DB" -Aqt) + OLD_H=$(echo "SELECT h_contract_terms FROM exchange.batch_deposits WHERE batch_deposit_serial_id=$SERIAL;" | psql "$DB" -Aqt) + echo -n "Manipulating row ${SERIAL} ..." +# shellcheck disable=SC2028 + echo "UPDATE exchange.batch_deposits SET h_contract_terms='\x12bb676444955c98789f219148aa31899d8c354a63330624d3d143222cf3bb8b8e16f69accd5a8773127059b804c1955696bf551dd7be62719870613332aa8d5' WHERE batch_deposit_serial_id=${SERIAL}" \ + | psql -At "$DB" # -# # Undo: -# echo "UPDATE exchange.deposits SET h_contract_terms='${OLD_H}' WHERE deposit_serial_id=$SERIAL" | psql -Aqt "$DB" + run_audit + check_auditor_running + + echo -n "Checking bad signature detection... " + check_report \ + "bad-sig-losses" \ + "problem_row_id" "$CSERIAL" + echo -n "Testing loss report... " + check_report \ + "bad-sig-losses" \ + "loss" "TESTKUDOS:3.02" + echo -n "Testing loss operation attribution... " + check_report \ + "bad-sig-losses" \ + "operation" "deposit" + echo -n "Testing total coin_irregular_loss balance update... " + check_balance \ + "coin_irregular_loss" \ + "TESTKUDOS:3.02" \ + "wrong total coin_irregular_loss" + + # Undo: + echo "UPDATE exchange.batch_deposits SET h_contract_terms='${OLD_H}' WHERE batch_deposit_serial_id=$SERIAL" \ + | psql -Aqt "$DB" } @@ -915,7 +903,8 @@ function test_5() { function test_6() { echo "===========6: known_coins signature wrong=================" # Modify denom_sig, so it is wrong - OLD_SIG=$(echo 'SELECT denom_sig FROM exchange.known_coins LIMIT 1;' | psql "$DB" -Aqt) + OLD_ROW=$(echo "SELECT known_coin_id FROM exchange.known_coins LIMIT 1;" | psql "$DB" -Aqt) + OLD_SIG=$(echo "SELECT denom_sig FROM exchange.known_coins WHERE known_coin_id=$OLD_ROW;" | psql "$DB" -Aqt) COIN_PUB=$(echo "SELECT coin_pub FROM exchange.known_coins WHERE denom_sig='$OLD_SIG';" | psql "$DB" -Aqt) # shellcheck disable=SC2028 echo "UPDATE exchange.known_coins SET denom_sig='\x0000000100000000287369672d76616c200a2028727361200a2020287320233542383731423743393036444643303442424430453039353246413642464132463537303139374131313437353746324632323332394644443146324643333445393939413336363430334233413133324444464239413833353833464536354442374335434445304441453035374438363336434541423834463843323843344446304144363030343430413038353435363039373833434431333239393736423642433437313041324632414132414435413833303432434346314139464635394244434346374436323238344143354544364131373739463430353032323241373838423837363535453434423145443831364244353638303232413123290a2020290a20290b' WHERE coin_pub='$COIN_PUB'" \ @@ -924,38 +913,28 @@ function test_6() { run_audit check_auditor_running - call_endpoint "bad-sig-losses" - ROW=$(jq -e .bad_sig_losses[0].row_id < ${MY_TMP_DIR}/bad-sig-losses.json) - if [ "$ROW" != "1" ] - then - exit_fail "Row wrong, got $ROW" - fi - - LOSS=$(jq -r .bad_sig_losses[0].loss < ${MY_TMP_DIR}/bad-sig-losses.json) - if [ "$LOSS" == "TESTKUDOS:0" ] - then - exit_fail "Wrong deposit bad signature loss, got $LOSS" - fi - - OP=$(jq -r .bad_sig_losses[0].operation < ${MY_TMP_DIR}/bad-sig-losses.json) - if [ "$OP" != "melt" ] - then - exit_fail "Wrong operation, got $OP" - fi - - call_endpoint "balances" "coin_irregular_loss" - LOSS=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/coin_irregular_loss.json) - if [ "$LOSS" == "TESTKUDOS:0" ] - then - exit_fail "Wrong total bad sig loss, got $LOSS" - fi - - #Undo + echo -n "Checking bad-signature-loss detected ..." + check_row \ + "bad-sig-losses" \ + "problem_row_id" "1" # Row reported is that of deposits or melt table, not known_coins + echo -n "Checking bad-signature-loss amount detected ..." + check_report_neg \ + "bad-sig-losses" \ + "loss" "TESTKUDOS:0" + echo -n "Checking bad-signature-loss operation detected ..." + check_report \ + "bad-sig-losses" \ + "operation" "deposit" + echo -n "Checking bad-signature-loss balance update ..." + check_not_balance \ + "coin_irregular_loss" \ + "TESTKUDOS:0" \ + "Wrong total bad sig loss" + + echo -n "Undo database change ... " echo "UPDATE exchange.known_coins SET denom_sig='$OLD_SIG' WHERE coin_pub='$COIN_PUB'" | psql -Aqt "$DB" - stop_auditor_httpd full_reload cleanup - } @@ -976,20 +955,11 @@ function test_7() { run_audit check_auditor_running - call_endpoint "bad-sig-losses" - OP=$(jq -r .bad_sig_losses[0].operation < ${MY_TMP_DIR}/bad-sig-losses.json) - if [ "$OP" != "withdraw" ] - then - exit_fail "Wrong operation, got $OP" - fi - - call_endpoint "balances" "reserves_total_bad_sig_loss" - LOSS=$(jq -r .bad_sig_losses[0].loss < ${MY_TMP_DIR}/bad-sig-losses.json) - LOSS_TOTAL=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/reserves_total_bad_sig_loss.json) - if [ "$LOSS" != "$LOSS_TOTAL" ] - then - exit_fail "Expected loss $LOSS and total loss $LOSS_TOTAL do not match" - fi + echo -n "Checking bad signature was detected ..." + check_report \ + "bad-sig-losses" \ + "operation" "withdraw" + echo -n "Checking loss was reported ..." if [ "$A_FRAC" != 0 ] then if [ "$A_FRAC" -lt 10 ] @@ -998,20 +968,21 @@ function test_7() { else A_PREV="" fi - if [ "$LOSS" != "TESTKUDOS:$A_VAL.$A_PREV$A_FRAC" ] - then - exit_fail "Expected loss TESTKUDOS:$A_VAL.$A_PREV$A_FRAC but got $LOSS" - fi + EXPECTED_LOSS="TESTKUDOS:$A_VAL.$A_PREV$A_FRAC" else - if [ "$LOSS" != "TESTKUDOS:$A_VAL" ] - then - exit_fail "Expected loss TESTKUDOS:$A_VAL but got $LOSS" - fi + EXPECTED_LOSS="TESTKUDOS:$A_VAL" fi + check_report \ + "bad-sig-losses" \ + "loss" "$EXPECTED_LOSS" + echo "Checking loss was totaled up ..." + check_balance \ + "reserves_total_bad_sig_loss" \ + "$EXPECTED_LOSS" \ + "wrong total bad sig loss" # Undo: echo "UPDATE exchange.reserves_out SET reserve_sig='$OLD_SIG' WHERE h_blind_ev='$HBE'" | psql -Aqt "$DB" - stop_auditor_httpd full_reload cleanup } @@ -1023,78 +994,46 @@ function test_8() { echo "===========8: wire-transfer-subject disagreement===========" # Technically, this call shouldn't be needed, as libeufin should already be stopped here. stop_libeufin - #TODO: see fixme - echo "FIXME: test needs update to new libeufin-bank schema" - #exit 0 - #OLD_ID=$(echo "SELECT id FROM NexusBankTransactions WHERE amount='10' AND currency='TESTKUDOS' ORDER BY id LIMIT 1;" | psql "${DB}" -Aqt) \ - # || exit_fail "Failed to SELECT FROM NexusBankTransactions nexus DB!" - #OLD_WTID=$(echo "SELECT \"reservePublicKey\" FROM TalerIncomingPayments WHERE payment='$OLD_ID';" \ - # | psql "${DB}" -Aqt) - #NEW_WTID="CK9QBFY972KR32FVA1MW958JWACEB6XCMHHKVFMCH1A780Q12SVG" - #echo "UPDATE TalerIncomingPayments SET \"reservePublicKey\"='$NEW_WTID' WHERE payment='$OLD_ID';" \ - # | psql "${DB}" -q \ - # || exit_fail "Failed to update TalerIncomingPayments" + OLD_ID=$(echo "SELECT exchange_incoming_id FROM libeufin_bank.taler_exchange_incoming JOIN libeufin_bank.bank_account_transactions ON (bank_transaction=bank_transaction_id) WHERE (amount).val=10 ORDER BY exchange_incoming_id LIMIT 1;" | psql "${DB}" -Aqt) \ + || exit_fail "Failed to SELECT FROM libeufin_bank.bank_account_transactions!" + OLD_WTID=$(echo "SELECT reserve_pub FROM libeufin_bank.taler_exchange_incoming WHERE exchange_incoming_id='$OLD_ID';" \ + | psql "${DB}" -Aqt) + NEW_WTID="\x77b4e23a41a0158299cdbe4d3247b42f907836d76dbc45c585c6a9beb196e6ca" + echo -n "Modifying $OLD_ID ..." + echo "UPDATE libeufin_bank.taler_exchange_incoming SET reserve_pub='$NEW_WTID' WHERE exchange_incoming_id='$OLD_ID';" \ + | psql "${DB}" -At \ + || exit_fail "Failed to update taler_exchange_incoming" + echo "DONE" run_audit check_auditor_running - #TODO: fix audit wire - #echo -n "Testing inconsistency detection... " - #DIAG=$(jq -r .reserve_in_amount_inconsistencies[0].diagnostic < test-audit-wire.json) - #if [ "x$DIAG" != "xwire subject does not match" ] - #then - # exit_fail "Diagnostic wrong: $DIAG (0)" - #fi - #WTID=$(jq -r .reserve_in_amount_inconsistencies[0].reserve_pub < test-audit-wire.json) - #if [ "$WTID" != "$OLD_WTID" ] && [ "$WTID" != "$NEW_WTID" ] - #then - # exit_fail "WTID reported wrong: $WTID (wanted $OLD_WTID or $NEW_WTID)" - #fi - #EX_A=$(jq -r .reserve_in_amount_inconsistencies[0].amount_exchange_expected < test-audit-wire.json) - #if [ "$WTID" = "$OLD_WTID" ] && [ "$EX_A" != "TESTKUDOS:10" ] - #then - # exit_fail "Amount reported wrong: $EX_A" - #fi - #if [ "$WTID" = "$NEW_WTID" ] && [ "$EX_A" != "TESTKUDOS:0" ] - #then - # exit_fail "Amount reported wrong: $EX_A" - #fi - #DIAG=$(jq -r .reserve_in_amount_inconsistencies[1].diagnostic < test-audit-wire.json) - #if [ "$DIAG" != "wire subject does not match" ] - #then - # exit_fail "Diagnostic wrong: $DIAG (1)" - #fi - #WTID=$(jq -r .reserve_in_amount_inconsistencies[1].reserve_pub < test-audit-wire.json) - #if [ "$WTID" != "$OLD_WTID" ] && [ "$WTID" != "$NEW_WTID" ] - #then - # exit_fail "WTID reported wrong: $WTID (wanted: $NEW_WTID or $OLD_WTID)" - #fi - #EX_A=$(jq -r .reserve_in_amount_inconsistencies[1].amount_exchange_expected < test-audit-wire.json) - #if [ "$WTID" = "$OLD_WTID" ] && [ "$EX_A" != "TESTKUDOS:10" ] - #then - # exit_fail "Amount reported wrong: $EX_A" - #fi - #if [ "$WTID" = "$NEW_WTID" ] && [ "$EX_A" != "TESTKUDOS:0" ] - #then - # exit_fail "Amount reported wrong: $EX_A" - #fi -# - #WIRED=$(jq -r .total_wire_in_delta_minus < test-audit-wire.json) - #if [ "$WIRED" != "TESTKUDOS:10" ] - #then - # exit_fail "Wrong total wire_in_delta_minus, got $WIRED" - #fi - #DELTA=$(jq -r .total_wire_in_delta_plus < test-audit-wire.json) - #if [ "$DELTA" != "TESTKUDOS:10" ] - #then - # exit_fail "Expected total wire delta plus wrong, got $DELTA" - #fi - #echo "PASS" + echo -n "Checking inconsistency diagnostic ..." + check_report \ + "reserve-in-inconsistency" \ + "diagnostic" "wire subject does not match" + echo -n "Checking expected balance report ..." + check_report \ + "reserve-in-inconsistency" \ + "amount_exchange_expected" "TESTKUDOS:10" + echo -n "Checking actual incoming balance report ..." + check_report \ + "reserve-in-inconsistency" \ + "amount_wired" "TESTKUDOS:0" + echo -n "Checking balance update (bad plus)..." + check_balance \ + "total_bad_amount_in_plus" \ + "TESTKUDOS:10" \ + "Wrong total_bad_amount_in_plus" + echo -n "Checking balance update (bad minus)..." + check_balance \ + "total_bad_amount_in_minus" \ + "TESTKUDOS:10" \ + "Wrong total_bad_amount_in_plus" # Undo database modification - #echo "UPDATE TalerIncomingPayments SET \"reservePublicKey\"='$OLD_WTID' WHERE payment='$OLD_ID';" \ - # | psql "${DB}" -q - stop_auditor_httpd + echo "UPDATE libeufin_bank.taler_exchange_incoming SET reserve_pub='$OLD_WTID' WHERE exchange_incoming_id='$OLD_ID';" \ + | psql "${DB}" -q full_reload cleanup } @@ -1106,35 +1045,29 @@ function test_9() { echo "===========9: wire-origin disagreement===========" # Technically, this call shouldn't be needed, as libeufin should already be stopped here. stop_libeufin - #TODO: see FIXME - echo "FIXME: test needs update to new libeufin-bank schema" - #exit 0 - #OLD_ID=$(echo "SELECT id FROM NexusBankTransactions WHERE amount='10' AND currency='TESTKUDOS' ORDER BY id LIMIT 1;" | psql "${DB}" -Aqt) - #OLD_ACC=$(echo 'SELECT "incomingPaytoUri" FROM TalerIncomingPayments WHERE payment='"'$OLD_ID';" | psql "${DB}" -Aqt) - #echo "UPDATE TalerIncomingPayments SET \"incomingPaytoUri\"='payto://iban/SANDBOXX/DE144373?receiver-name=New+Exchange+Company' WHERE payment='$OLD_ID';" \ - # | psql "${DB}" -q + OLD_ID=$(echo "SELECT bank_transaction FROM libeufin_bank.taler_exchange_incoming JOIN libeufin_bank.bank_account_transactions ON (bank_transaction=bank_transaction_id) WHERE (amount).val=10 ORDER BY bank_transaction LIMIT 1;" | psql "${DB}" -Aqt) \ + || exit_fail "Failed to SELECT FROM libeufin_bank.bank_account_transactions!" + OLD_ACC=$(echo "SELECT debtor_payto FROM libeufin_bank.bank_account_transactions WHERE bank_transaction_id='$OLD_ID';" | psql "${DB}" -Aqt) + + echo -n "Modifying $OLD_ID ..." + echo "UPDATE libeufin_bank.bank_account_transactions SET debtor_payto='payto://iban/DE144373' WHERE bank_transaction_id='$OLD_ID';" \ + | psql "${DB}" -At run_audit check_auditor_running - #TODO: fix helper wire - #echo -n "Testing inconsistency detection... " - #AMOUNT=$(jq -r .misattribution_in_inconsistencies[0].amount < test-audit-wire.json) - #if test "x$AMOUNT" != "xTESTKUDOS:10" - #then - # exit_fail "Reported amount wrong: $AMOUNT" - #fi - #AMOUNT=$(jq -r .total_misattribution_in < test-audit-wire.json) - #if test "x$AMOUNT" != "xTESTKUDOS:10" - #then - # exit_fail "Reported total amount wrong: $AMOUNT" - #fi - echo PASS - + echo -n "Testing inconsistency detection... " + check_report \ + misattribution-in-inconsistency \ + "amount" "TESTKUDOS:10" + echo -n "Testing balance update... " + check_balance \ + "total_misattribution_in" \ + "TESTKUDOS:10" \ + "Reported total_misattribution_in wrong" # Undo database modification - #echo "UPDATE TalerIncomingPayments SET \"incomingPaytoUri\"='$OLD_ACC' WHERE payment='$OLD_ID';" \ - # | psql "${DB}" -q - stop_auditor_httpd + echo "UPDATE libeufin_bank.bank_account_transactions SET debtor_payto='$OLD_ACC' WHERE bank_transaction_id='$OLD_ID';" \ + | psql "${DB}" -Atq full_reload cleanup } @@ -1146,104 +1079,83 @@ function test_10() { echo "===========10: wire-timestamp disagreement===========" # Technically, this call shouldn't be needed, as libeufin should already be stopped here. stop_libeufin - #TODO: see fixme - #echo "FIXME: test needs update to new libeufin-bank schema" - #exit 0 - #OLD_ID=$(echo "SELECT id FROM NexusBankTransactions WHERE amount='10' AND currency='TESTKUDOS' ORDER BY id LIMIT 1;" | psql "${DB}" -Aqt) - #OLD_DATE=$(echo "SELECT \"timestampMs\" FROM TalerIncomingPayments WHERE payment='$OLD_ID';" | psql "${DB}" -Aqt) - #echo "UPDATE TalerIncomingPayments SET \"timestampMs\"=$NOW_MS WHERE payment=$OLD_ID;" | psql "${DB}" -q + OLD_ID=$(echo "SELECT bank_transaction FROM libeufin_bank.taler_exchange_incoming JOIN libeufin_bank.bank_account_transactions ON (bank_transaction=bank_transaction_id) WHERE (amount).val=10 ORDER BY exchange_incoming_id LIMIT 1;" | psql "${DB}" -Aqt) \ + || exit_fail "Failed to SELECT FROM libeufin_bank.bank_account_transactions!" + OLD_DATE=$(echo "SELECT transaction_date FROM libeufin_bank.bank_account_transactions WHERE bank_transaction_id='$OLD_ID';" | psql "${DB}" -Aqt) + echo -n "Modifying $OLD_ID ..." + echo "UPDATE libeufin_bank.bank_account_transactions SET transaction_date=$NOW_MS WHERE bank_transaction_id=$OLD_ID;" \ + | psql "${DB}" -At run_audit check_auditor_running - #TODO: fix helper wire - #echo -n "Testing inconsistency detection... " - #DIAG=$(jq -r .row_minor_inconsistencies[0].diagnostic < test-audit-wire.json) - #if test "x$DIAG" != "xexecution date mismatch" - #then - # exit_fail "Reported diagnostic wrong: $DIAG" - #fi - #TABLE=$(jq -r .row_minor_inconsistencies[0].table < test-audit-wire.json) - #if test "x$TABLE" != "xreserves_in" - #then - # exit_fail "Reported table wrong: $TABLE" - #fi - #echo "PASS" - + echo -n "Testing inconsistency detection diagnostic... " + check_report \ + row-minor-inconsistencies \ + "diagnostic" "execution date mismatch" + echo -n "Testing inconsistency detection table... " + check_report \ + row-minor-inconsistencies \ + "row_table" "reserves_in" # Undo database modification - #echo "UPDATE TalerIncomingPayments SET \"timestampMs\"='$OLD_DATE' WHERE payment=$OLD_ID;" | psql "${DB}" -q - stop_auditor_httpd + echo "UPDATE libeufin_bank.bank_account_transactions SET transaction_date=$OLD_DATE WHERE bank_transaction_id=$OLD_ID;" \ + | psql "${DB}" -Aqt full_reload cleanup } # Test for extra outgoing wire transfer. -# In case of changing the subject in the Nexus -# ingested table: '.batches[0].batchTransactions[0].details.unstructuredRemittanceInformation' function test_11() { echo "===========11: spurious outgoing transfer ===========" # Technically, this call shouldn't be needed, as libeufin should already be stopped here. stop_libeufin - echo "FIXME: test needs update to new libeufin-bank schema" - #TODO: see fixme - #exit 0 - #OLD_ID=$(echo "SELECT id FROM NexusBankTransactions WHERE amount='10' AND currency='TESTKUDOS' ORDER BY id LIMIT 1;" | psql "${DB}" -Aqt) - #OLD_TX=$(echo "SELECT \"transactionJson\" FROM NexusBankTransactions WHERE id='$OLD_ID';" | psql "${DB}" -Aqt) - # Change wire transfer to be FROM the exchange (#2) to elsewhere! - # (Note: this change also causes a missing incoming wire transfer, but - # this test is only concerned about the outgoing wire transfer - # being detected as such, and we simply ignore the other - # errors being reported.) - #OTHER_IBAN=$(echo -e "SELECT iban FROM BankAccounts WHERE label='fortytwo'" | psql "${DB}" -Aqt) - #NEW_TX=$(echo "$OLD_TX" | jq .batches[0].batchTransactions[0].details.creditDebitIndicator='"DBIT"' | jq 'del(.batches[0].batchTransactions[0].details.debtor)' | jq 'del(.batches[0].batchTransactions[0].details.debtorAccount)' | jq 'del(.batches[0].batchTransactions[0].details.debtorAgent)' | jq '.batches[0].batchTransactions[0].details.creditor'='{"name": "Forty Two"}' | jq .batches[0].batchTransactions[0].details.creditorAccount='{"iban": "'"$OTHER_IBAN"'"}' | jq .batches[0].batchTransactions[0].details.creditorAgent='{"bic": "SANDBOXX"}' | jq .batches[0].batchTransactions[0].details.unstructuredRemittanceInformation='"CK9QBFY972KR32FVA1MW958JWACEB6XCMHHKVFMCH1A780Q12SVG http://exchange.example.com/"') - #echo -e "UPDATE NexusBankTransactions SET \"transactionJson\"='""$NEW_TX""' WHERE id=$OLD_ID" \ - # | psql "${DB}" -q - # Now fake that the exchange prepared this payment (= it POSTed to /transfer) - # This step is necessary, because the TWG table that accounts for outgoing - # payments needs it. Worth noting here is the column 'rawConfirmation' that - # points to the transaction from the main Nexus ledger; without that column set, - # a prepared payment won't appear as actually outgoing. - #echo -e "INSERT INTO PaymentInitiations (\"bankAccount\",\"preparationDate\",\"submissionDate\",sum,currency,\"endToEndId\",\"paymentInformationId\",\"instructionId\",subject,\"creditorIban\",\"creditorBic\",\"creditorName\",submitted,\"messageId\",\"rawConfirmation\") VALUES (1,1,1,10,'TESTKUDOS','NOTGIVEN','unused','unused','CK9QBFY972KR32FVA1MW958JWACEB6XCMHHKVFMCH1A780Q12SVG http://exchange.example.com/','""$OTHER_IBAN""','SANDBOXX','Forty Two',false,1,$OLD_ID)" \ - # | psql "${DB}" -q - # Now populate the TWG table that accounts for outgoing payments, in - # order to let /history/outgoing return one result. - #echo -e "INSERT INTO TalerRequestedPayments (facade,payment,\"requestUid\",amount,\"exchangeBaseUrl\",wtid,\"creditAccount\") VALUES (1,1,'unused','TESTKUDOS:10','http://exchange.example.com/','CK9QBFY972KR32FVA1MW958JWACEB6XCMHHKVFMCH1A780Q12SVG','payto://iban/SANDBOXX/""$OTHER_IBAN""?receiver-name=Forty+Two')" \ - # | psql "${DB}" -q + launch_libeufin + OTHER_IBAN=$(echo -e "SELECT internal_payto FROM libeufin_bank.bank_accounts ba JOIN libeufin_bank.customers bc ON (ba.owning_customer_id = bc.customer_id) WHERE username='fortytwo'" | psql "${DB}" -Aqt) + + await_bank + echo -n "Creating bogus transfer... " + STATUS=$(curl -H "Content-Type: application/json" -X POST \ + -u 'exchange:x' \ + http://localhost:8082/accounts/exchange/taler-wire-gateway/transfer \ + -d '{"credit_account":"'"$OTHER_IBAN"'","exchange_base_url":"http://exchange.example.com/","amount":"TESTKUDOS:10","wtid":"7X93HVKPHE0KAQ6KHSB3921KJGSVDMQFHMQV17885YJDMZ20XS9G","request_uid":"7X93HKPHE0KAQ6KHSB3921KJGSVDMQFHMQV17885YJDMZ20XS9G7X93HVKPHE0KAQ6KHSB3921KJGSVDMQFHMQV17885YJDMZ20XS9G"}' \ + -w "%{http_code}" -s -o /dev/null) + + if [ "$STATUS" != "200" ] + then + exit_fail "Expected 200 OK. Got: $STATUS" + fi + echo "DONE" + stop_libeufin run_audit check_auditor_running - #TODO: fix helper wire - #echo -n "Testing inconsistency detection... " - #AMOUNT=$(jq -r .wire_out_amount_inconsistencies[0].amount_wired < test-audit-wire.json) - #if [ "x$AMOUNT" != "xTESTKUDOS:10" ] - #then - # exit_fail "Reported wired amount wrong: $AMOUNT" - #fi - #AMOUNT=$(jq -r .total_wire_out_delta_plus < test-audit-wire.json) - #if [ "x$AMOUNT" != "xTESTKUDOS:10" ] - #then - # exit_fail "Reported total plus amount wrong: $AMOUNT" - #fi - #AMOUNT=$(jq -r .total_wire_out_delta_minus < test-audit-wire.json) - #if [ "x$AMOUNT" != "xTESTKUDOS:0" ] - #then - # exit_fail "Reported total minus amount wrong: $AMOUNT" - #fi - #AMOUNT=$(jq -r .wire_out_amount_inconsistencies[0].amount_justified < test-audit-wire.json) - #if [ "x$AMOUNT" != "xTESTKUDOS:0" ] - #then - # exit_fail "Reported justified amount wrong: $AMOUNT" - #fi - #DIAG=$(jq -r .wire_out_amount_inconsistencies[0].diagnostic < test-audit-wire.json) - #if [ "x$DIAG" != "xjustification for wire transfer not found" ] - #then - # exit_fail "Reported diagnostic wrong: $DIAG" - #fi - #echo "PASS" - - stop_auditor_httpd + echo -n "Testing inconsistency detection... " + check_report \ + "wire-out-inconsistency" \ + "claimed" \ + "TESTKUDOS:10" + echo -n "Testing bad_amount_plus balance reporting... " + check_balance \ + "total_bad_amount_out_plus" \ + "TESTKUDOS:10" \ + "reported total_bad_amount_plus wrong" + echo -n "Testing bad_amount_minus balance reporting... " + check_balance \ + "total_bad_amount_out_minus" \ + "TESTKUDOS:0" \ + "reported total_bad_amount_minus wrong" + echo -n "Testing expected amount is correct... " + check_report \ + "wire-out-inconsistency" \ + "expected" \ + "TESTKUDOS:0" + echo -n "Testing diagnostic message is correct... " + check_report \ + "wire-out-inconsistency" \ + "diagnostic" \ + "missing justification for outgoing wire transfer" full_reload } @@ -1257,26 +1169,19 @@ function test_12() { run_audit check_auditor_running - echo -n "Testing hung refresh detection... " - - call_endpoint "refreshes-hanging" call_endpoint "balances" - call_endpoint "balances" "total_refresh_hanging" - HANG=$(jq -er .refreshes_hanging[0].amount < ${MY_TMP_DIR}/refreshes-hanging.json) - TOTAL_HANG=$(jq -er .balances[0].balance_value < ${MY_TMP_DIR}/total_refresh_hanging.json) - if [ "$HANG" = "TESTKUDOS:0" ] - then - exit_fail "Hanging amount zero" - fi - if [ "$TOTAL_HANG" = "TESTKUDOS:0" ] - then - exit_fail "Total hanging amount zero" - fi - echo "PASS" + echo -n "Checking hanging refresh detected ... " + check_report_neg \ + "refreshes-hanging" \ + "amount" "TESTKUDOS:0" + echo -n "Checking total balance updated ... " + check_not_balance \ + "total_refresh_hanging" \ + "TESTKUDOS:0" \ + "Hanging amount zero" # cannot easily undo DELETE, hence full reload full_reload - stop_auditor_httpd } @@ -1296,31 +1201,21 @@ function test_13() { echo -n "Testing inconsistency detection... " - call_endpoint "bad-sig-losses" - call_endpoint "balances" "coin_irregular_loss" - - OP=$(jq -er .bad_sig_losses[0].operation < ${MY_TMP_DIR}/bad-sig-losses.json) - if [ "$OP" != "melt" ] - then - exit_fail "Operation wrong, got $OP" - fi - - LOSS=$(jq -er .bad_sig_losses[0].loss < ${MY_TMP_DIR}/bad-sig-losses.json) - TOTAL_LOSS=$(jq -er .balances[0].balance_value < ${MY_TMP_DIR}/coin_irregular_loss.json) - if [ "$LOSS" != "$TOTAL_LOSS" ] - then - exit_fail "Loss inconsistent, got $LOSS and $TOTAL_LOSS" - fi - if [ "$TOTAL_LOSS" = "TESTKUDOS:0" ] - then - exit_fail "Loss zero" - fi - - echo "PASS" + check_report \ + "bad-sig-losses" \ + "operation" "melt" + echo -n "Checking loss amount reported ..." + check_report \ + "bad-sig-losses" \ + "loss" "TESTKUDOS:3.96" + echo -n "Checking loss amount totaled ..." + check_balance \ + "coin_irregular_loss" \ + "TESTKUDOS:3.96" \ + "Loss inconsistent" # cannot easily undo DELETE, hence full reload full_reload - stop_auditor_httpd } @@ -1339,24 +1234,17 @@ function test_14() { post_audit check_auditor_running - call_endpoint "row-inconsistency" - - echo -n "Testing inconsistency detection... " - TABLE=$(jq -r .row_inconsistency[0].row_table < ${MY_TMP_DIR}/row-inconsistency.json) - if [ "$TABLE" != "wire-fee" ] - then - exit_fail "Reported table wrong: $TABLE" - fi - DIAG=$(jq -r .row_inconsistency[0].diagnostic < ${MY_TMP_DIR}/row-inconsistency.json) - if [ "$DIAG" != "wire fee signature invalid at given time" ] - then - exit_fail "Reported diagnostic wrong: $DIAG" - fi - echo "PASS" + echo -n "Checking wire-fee inconsistency was detected ..." + check_report \ + "row-inconsistency" \ + "row_table" "wire-fee" + echo -n "Checking diagnostic was set correctly ..." + check_report \ + "row-inconsistency" \ + "diagnostic" "wire fee signature invalid at given time" # cannot easily undo aggregator, hence full reload full_reload - stop_auditor_httpd } @@ -1374,15 +1262,10 @@ function test_15() { run_audit check_auditor_running - call_endpoint "bad-sig-losses" - - echo -n "Testing inconsistency detection... " - OP=$(jq -r .bad_sig_losses[0].operation < ${MY_TMP_DIR}/bad-sig-losses.json) - if [ "$OP" != "deposit" ] - then - exit_fail "Reported operation wrong: $OP" - fi - echo "PASS" + echo -n "Checking broken deposit signature detected ..." + check_report \ + "bad-sig-losses" \ + "operation" "deposit" # Restore DB echo "UPDATE exchange.batch_deposits SET wire_salt='$SALT' WHERE batch_deposit_serial_id=1;" \ @@ -1396,83 +1279,89 @@ function test_15() { function test_16() { echo "===========16: incorrect wire_out amount=================" - # Check wire transfer lag reported (no aggregator!) - # First, we need to run the aggregator so we even # have a wire_out to modify. pre_audit aggregator check_auditor_running -#TODO FIX LIBEUFIN - #stop_libeufin - #OLD_AMOUNT=$(echo "SELECT amount FROM TalerRequestedPayments WHERE id='1';" | psql "${DB}" -Aqt) - #NEW_AMOUNT="TESTKUDOS:50" - #echo "UPDATE TalerRequestedPayments SET amount='${NEW_AMOUNT}' WHERE id='1';" \ - # | psql "${DB}" -q - #launch_libeufin - #audit_only - #check_auditor_running -# - #echo -n "Testing inconsistency detection... " -# - #AMOUNT=$(jq -r .wire_out_amount_inconsistencies[0].amount_justified < test-audit-wire.json) - #if [ "$AMOUNT" != "$OLD_AMOUNT" ] - #then - # exit_fail "Reported justified amount wrong: $AMOUNT" - #fi - #AMOUNT=$(jq -r .wire_out_amount_inconsistencies[0].amount_wired < test-audit-wire.json) - #if [ "$AMOUNT" != "$NEW_AMOUNT" ] - #then - # exit_fail "Reported wired amount wrong: $AMOUNT" - #fi - #TOTAL_AMOUNT=$(jq -r .total_wire_out_delta_minus < test-audit-wire.json) - #if [ "$TOTAL_AMOUNT" != "TESTKUDOS:0" ] - #then - # exit_fail "Reported total wired amount minus wrong: $TOTAL_AMOUNT" - #fi - #TOTAL_AMOUNT=$(jq -r .total_wire_out_delta_plus < test-audit-wire.json) - #if [ "$TOTAL_AMOUNT" = "TESTKUDOS:0" ] - #then - # exit_fail "Reported total wired amount plus wrong: $TOTAL_AMOUNT" - #fi - #echo "PASS" -# - #stop_libeufin - #echo "Second modification: wire nothing" - #NEW_AMOUNT="TESTKUDOS:0" - #echo "UPDATE TalerRequestedPayments SET amount='${NEW_AMOUNT}' WHERE id='1';" \ - # | psql "${DB}" -q - #launch_libeufin - #audit_only - #stop_libeufin - #echo -n "Testing inconsistency detection... " -# - #AMOUNT=$(jq -r .wire_out_amount_inconsistencies[0].amount_justified < test-audit-wire.json) - #if [ "$AMOUNT" != "$OLD_AMOUNT" ] - #then - # exit_fail "Reported justified amount wrong: $AMOUNT" - #fi - #AMOUNT=$(jq -r .wire_out_amount_inconsistencies[0].amount_wired < test-audit-wire.json) - #if [ "$AMOUNT" != "$NEW_AMOUNT" ] - #then - # exit_fail "Reported wired amount wrong: $AMOUNT" - #fi - #TOTAL_AMOUNT=$(jq -r .total_wire_out_delta_minus < test-audit-wire.json) - #if [ "$TOTAL_AMOUNT" != "$OLD_AMOUNT" ] - #then - # exit_fail "Reported total wired amount minus wrong: $TOTAL_AMOUNT (wanted $OLD_AMOUNT)" - #fi - #TOTAL_AMOUNT=$(jq -r .total_wire_out_delta_plus < test-audit-wire.json) - #if [ "$TOTAL_AMOUNT" != "TESTKUDOS:0" ] - #then - # exit_fail "Reported total wired amount plus wrong: $TOTAL_AMOUNT" - #fi - #echo "PASS" -# - #post_audit + stop_libeufin + OLD_AMOUNT_VAL=$(echo "SELECT (amount).val FROM libeufin_bank.bank_account_transactions WHERE debtor_name='Exchange Company' AND direction='debit';" | psql "${DB}" -Aqt) + OLD_AMOUNT_FRAC=$(echo "SELECT (amount).frac FROM libeufin_bank.bank_account_transactions WHERE debtor_name='Exchange Company' AND direction='debit';" | psql "${DB}" -Aqt) + if [[ 0 = "$OLD_AMOUNT_FRAC" ]] + then + OLD_AMOUNT="TESTKUDOS:${OLD_AMOUNT_VAL}" + else + OLD_AMOUNT_CENTS=$(($OLD_AMOUNT_FRAC / 1000000)) + if [[ 10 -gt "$OLD_AMOUNT_CENTS" ]] + then + OLD_AMOUNT="TESTKUDOS:${OLD_AMOUNT_VAL}.0${OLD_AMOUNT_CENTS}" + else + OLD_AMOUNT="TESTKUDOS:${OLD_AMOUNT_VAL}.${OLD_AMOUNT_CENTS}" + fi + fi + NEW_AMOUNT="TESTKUDOS:50" + echo "UPDATE libeufin_bank.bank_account_transactions SET amount=(50,0) WHERE debtor_name='Exchange Company';" \ + | psql "${DB}" -q + launch_libeufin + await_bank + + audit_only + check_auditor_running + + echo -n "Testing wire-out-inconsistency-expected... " + check_report \ + "wire-out-inconsistency" \ + "expected" \ + "$OLD_AMOUNT" + echo -n "Testing wire-out-inconsistency-claimed... " + check_report \ + "wire-out-inconsistency" \ + "claimed" \ + "$NEW_AMOUNT" + echo -n "Testing bad_amount_minus balance reporting... " + check_balance \ + "total_bad_amount_out_minus" \ + "TESTKUDOS:0" \ + "reported total_bad_amount_minus wrong" + echo -n "Testing bad_amount_plus balance reporting... " + check_not_balance \ + "total_bad_amount_out_plus" \ + "TESTKUDOS:0" \ + "reported total_bad_amount_plus wrong" + + stop_libeufin + echo "Second modification: wire nothing" + NEW_AMOUNT="TESTKUDOS:0" + echo "UPDATE libeufin_bank.bank_account_transactions SET amount=(0,0) WHERE debtor_name='Exchange Company';" \ + | psql "${DB}" -q + launch_libeufin + audit_only + stop_libeufin + + echo -n "Testing wire-out-inconsistency-expected... " + check_report \ + "wire-out-inconsistency" \ + "expected" \ + "$OLD_AMOUNT" + echo -n "Testing wire-out-inconsistency-claimed... " + check_report \ + "wire-out-inconsistency" \ + "claimed" \ + "$NEW_AMOUNT" + echo -n "Testing bad_amount_minus balance reporting... " + check_balance \ + "total_bad_amount_out_minus" \ + "$OLD_AMOUNT" \ + "reported total_bad_amount_minus wrong" + echo -n "Testing bad_amount_plus balance reporting... " + check_balance \ + "total_bad_amount_out_plus" \ + "TESTKUDOS:0" \ + "reported total_bad_amount_plus wrong" + + post_audit # cannot easily undo aggregator, hence full reload full_reload - stop_auditor_httpd } @@ -1482,39 +1371,41 @@ function test_17() { # First, we need to run the aggregator so we even # have a wire_out to modify. -#TODO FIX libeufin -# pre_audit aggregator -# stop_libeufin -# OLD_ID=1 -# OLD_PREP=$(echo "SELECT payment FROM TalerRequestedPayments WHERE id='${OLD_ID}';" | psql "${DB}" -Aqt) -# OLD_DATE=$(echo "SELECT \"preparationDate\" FROM PaymentInitiations WHERE id='${OLD_ID}';" | psql "${DB}" -Aqt) -# # Note: need - interval '1h' as "NOW()" may otherwise be exactly what is already in the DB -# # (due to rounding, if this machine is fast...) -# NOW_1HR=$(( $(date +%s) - 3600)) -# echo "UPDATE PaymentInitiations SET \"preparationDate\"='$NOW_1HR' WHERE id='${OLD_PREP}';" \ -# | psql "${DB}" -q -# launch_libeufin -# echo "DONE" -# audit_only -# post_audit -# check_auditor_running -# -# echo -n "Testing inconsistency detection... " -# TABLE=$(jq -r .row_minor_inconsistencies[0].table < test-audit-wire.json) -# if [ "$TABLE" != "wire_out" ] -# then -# exit_fail "Reported table wrong: $TABLE" -# fi -# DIAG=$(jq -r .row_minor_inconsistencies[0].diagnostic < test-audit-wire.json) -# DIAG=$(echo "$DIAG" | awk '{print $1 " " $2 " " $3}') -# if [ "$DIAG" != "execution date mismatch" ] -# then -# exit_fail "Reported diagnostic wrong: $DIAG" -# fi -# echo "PASS" -# -# # cannot easily undo aggregator, hence full reload -# full_reload + pre_audit aggregator + stop_libeufin + + echo -n "Modifying timestamp of existing wire_out transaction... " + OLD_DATE=$(echo "SELECT transaction_date FROM libeufin_bank.bank_account_transactions WHERE debtor_name='Exchange Company' AND direction='debit';" | psql "${DB}" -Aqt) + # Note: need - interval '1h' as "NOW()" may otherwise be exactly what is already in the DB + # (due to rounding, if this machine is fast...) + NOW_1HR=$(( $(date +%s) - 3600)) + + echo "UPDATE libeufin_bank.bank_account_transactions SET transaction_date='${NOW_1HR}000000' WHERE debtor_name='Exchange Company';" \ + | psql "${DB}" -q + echo "DONE" + + launch_libeufin + await_bank + audit_only + post_audit + check_auditor_running + + echo -n "Testing inconsistency detection... " + check_report \ + row-minor-inconsistencies \ + "row_table" "wire_out" + + echo -n "Testing inconsistency diagnostic... " + call_endpoint "row-minor-inconsistencies" + DIAG=$(jq -r .row_minor_inconsistencies[0].diagnostic < "${MY_TMP_DIR}/row-minor-inconsistencies.json" | awk '{print $1 " " $2 " " $3}') + if [ "$DIAG" != "execution date mismatch" ] + then + exit_fail "Reported diagnostic wrong: $DIAG" + fi + echo "PASS" + + # cannot easily undo aggregator, hence full reload + full_reload } @@ -1528,48 +1419,35 @@ function test_18() { run_audit check_auditor_running - call_endpoint "reserve-balance-summary-wrong-inconsistency" - call_endpoint "emergency" - call_endpoint "emergency-by-count" - call_endpoint "amount-arithmetic-inconsistency" - call_endpoint "balances" "coins_emergencies_loss_by_count" - call_endpoint "balances" "coins_emergencies_loss" - + echo -n "Testing bad reserve balance summary reporting ... " + # note: we check "suppressed" to only check the *existence* here. + check_report \ + "reserve-balance-summary-wrong-inconsistency" \ + "suppressed" "false" echo -n "Testing emergency detection... " - jq -e .reserve_balance_summary_wrong_inconsistency[0] \ - < ${MY_TMP_DIR}/reserve-balance-summary-wrong-inconsistency.json \ - > /dev/null \ - || exit_fail "Reserve balance inconsistency not detected" - jq -e .emergency[0] \ - < ${MY_TMP_DIR}/emergency.json \ - > /dev/null \ - || exit_fail "Emergency not detected" - jq -e .emergency_by_count[0] \ - < ${MY_TMP_DIR}/emergency-by-count.json \ - > /dev/null \ - || exit_fail "Emergency by count not detected" - jq -e .amount_arithmetic_inconsistency[0] \ - < ${MY_TMP_DIR}/amount-arithmetic-inconsistency.json \ - > /dev/null \ - || exit_fail "Escrow balance calculation impossibility not detected" - echo "PASS" - + check_report \ + "emergency" \ + "suppressed" "false" + echo -n "Testing emergency detection by count... " + check_report \ + "emergency-by-count" \ + "suppressed" "false" + echo -n "Testing escrow balance calculation impossibility... " + check_report \ + "amount-arithmetic-inconsistency" \ + "suppressed" "false" + echo -n "Testing loss calculation by count... " + check_not_balance \ + "coins_emergencies_loss_by_count" \ + "TESTKUDOS:0" \ + "Emergency by count loss not reported" echo -n "Testing loss calculation... " - AMOUNT=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/coins_emergencies_loss_by_count.json) - if [ "$AMOUNT" == "TESTKUDOS:0" ] - then - exit_fail "Reported amount wrong: $AMOUNT" - fi - AMOUNT=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/coins_emergencies_loss.json) - if [ "$AMOUNT" == "TESTKUDOS:0" ] - then - exit_fail "Reported amount wrong: $AMOUNT" - fi - echo "PASS" - + check_not_balance \ + "coins_emergencies_loss" \ + "TESTKUDOS:0" \ + "Emergency loss not reported" # cannot easily undo broad DELETE operation, hence full reload full_reload - stop_auditor_httpd } @@ -1589,30 +1467,17 @@ function test_19() { | psql -Aqt "$DB" echo "UPDATE exchange.reserves SET current_balance.val=${VAL_DELTA}+(current_balance).val,expiration_date='${NEW_EXP}' WHERE reserve_pub='${RES_PUB}';" \ | psql -Aqt "$DB" -#TODO fix helper wire # Need to run with the aggregator so the reserve closure happens - #run_audit aggregator - check_auditor_running - - call_endpoint "reserve-not-closed-inconsistency" - - echo -n "Testing reserve closure was done correctly... " - - jq -e .reserve_not_closed_inconsistencies[0] < \ - ${MY_TMP_DIR}/reserve-not-closed-inconsistency.json > /dev/null \ - && exit_fail "Unexpected reserve not closed inconsistency detected" - - echo "PASS" - - #TODO fix helepr wire - #echo -n "Testing no bogus transfers detected... " - #jq -e .wire_out_amount_inconsistencies[0] < test-audit-wire.json > /dev/null && exit_fail "Unexpected wire out inconsistency detected in run with reserve closure" + run_audit aggregator + check_auditor_running - echo "PASS" + echo -n "Testing reserve closure was done correctly... " + check_no_report "reserve-not-closed-inconsistency" + echo -n "Testing no bogus transfers detected... " + check_no_report "wire-out-inconsistency" - # cannot easily undo aggregator, hence full reload - full_reload - stop_auditor_httpd + # cannot easily undo aggregator, hence full reload + full_reload } @@ -1634,21 +1499,15 @@ function test_20() { run_audit check_auditor_running - call_endpoint "reserve-not-closed-inconsistency" - call_endpoint "balances" "total_balance_reserve_not_closed" - echo -n "Testing reserve closure missing detected... " - jq -e .reserve_not_closed_inconsistency[0] \ - < ${MY_TMP_DIR}/reserve-not-closed-inconsistency.json\ - > /dev/null \ - || exit_fail "Reserve not closed inconsistency not detected" - echo "PASS" - - AMOUNT=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/total_balance_reserve_not_closed.json) - if [ "$AMOUNT" == "TESTKUDOS:0" ] - then - exit_fail "Reported total amount wrong: $AMOUNT" - fi + check_report \ + "reserve-not-closed-inconsistency" \ + "suppressed" "false" + echo -n "Testing balance updated correctly... " + check_not_balance \ + "total_balance_reserve_not_closed" \ + "TESTKUDOS:0" \ + "Reported total amount wrong" # Undo echo "UPDATE exchange.reserves_in SET execution_date='${OLD_TIME}',credit.val=${OLD_VAL} WHERE reserve_in_serial_id=1;" \ @@ -1657,7 +1516,6 @@ function test_20() { | psql -Aqt "$DB" full_reload - stop_auditor_httpd } @@ -1677,42 +1535,38 @@ function test_21() { | psql -Aqt "$DB" echo "UPDATE exchange.reserves SET current_balance.val=${VAL_DELTA}+(current_balance).val,expiration_date='${NEW_EXP}' WHERE reserve_pub='${RES_PUB}';" \ | psql -Aqt "$DB" -#TODO FIX AUDITOR wire - # Need to first run the aggregator so the transfer is marked as done exists -# pre_audit aggregator -# stop_libeufin -# # remove transaction from bank DB -# # Currently emulating this (to be deleted): -# echo "DELETE FROM TalerRequestedPayments WHERE amount='TESTKUDOS:${VAL_DELTA}'" \ -# | psql "${DB}" -q -# launch_libeufin -# audit_only -# post_audit -# check_auditor_running -# -# call_endpoint "reserve-not-closed-inconsistency" -# -# -# echo -n "Testing lack of reserve closure transaction detected... " -# -# jq -e .reserve_lag_details[0] \ -# < test-audit-wire.json \ -# > /dev/null \ -# || exit_fail "Reserve closure lag not detected" -# -# AMOUNT=$(jq -r .reserve_lag_details[0].amount < test-audit-wire.json) -# if [ "$AMOUNT" != "TESTKUDOS:${VAL_DELTA}" ] -# then -# exit_fail "Reported total amount wrong: $AMOUNT" -# fi -# AMOUNT=$(jq -r .total_closure_amount_lag < test-audit-wire.json) -# if [ "$AMOUNT" != "TESTKUDOS:${VAL_DELTA}" ] -# then -# exit_fail "Reported total amount wrong: $AMOUNT" -# fi - echo "PASS" + # Need to first run the aggregator so the transfer is marked as done + pre_audit aggregator + stop_libeufin + + # remove wire transfer from bank DB + echo "DELETE FROM libeufin_bank.bank_account_transactions WHERE debtor_name='Exchange Company';" \ + | psql "${DB}" -q + + launch_libeufin + audit_only + post_audit + check_auditor_running + echo -n "Testing reserve_in inconsistency detection... " + check_report \ + row-minor-inconsistencies \ + "row_table" "reserves_in" + + echo -n "Testing lack of reserve closure transaction detected... " + check_report \ + "closure-lags" \ + "suppressed" "false" + echo -n "Checking closure lag amount ..." + check_report \ + "closure-lags" \ + "amount" "TESTKUDOS:${VAL_DELTA}" + echo -n "Checking closure lag total balance ..." + check_balance \ + "total_closure_amount_lag" \ + "TESTKUDOS:${VAL_DELTA}" \ + "Reported total_closure_amount_lag wrong" # cannot easily undo aggregator, hence full reload full_reload } @@ -1735,19 +1589,16 @@ function test_22() { run_audit check_auditor_running - call_endpoint "denomination-key-validity-withdraw-inconsistency" - echo -n "Testing inconsistency detection... " - jq -e .denomination_key_validity_withdraw_inconsistency[0] < ${MY_TMP_DIR}/denomination-key-validity-withdraw-inconsistency.json \ - > /dev/null || exit_fail "Denomination key withdraw inconsistency for $S_DENOM not detected" - - echo "PASS" + check_report \ + "denomination-key-validity-withdraw-inconsistency" \ + "suppressed" "false" + call_endpoint "denomination-key-validity-withdraw-inconsistency" # Undo modification echo "UPDATE exchange.denominations SET expire_withdraw=${OLD_WEXP} WHERE denominations_serial='${S_DENOM}';" | psql -Aqt "$DB" full_reload - stop_auditor_httpd } @@ -1768,33 +1619,23 @@ function test_23() { check_auditor_running echo -n "Testing inconsistency detection... " - - call_endpoint "wire-out-inconsistency" - call_endpoint "balances" "aggregator_total_wire_out_delta_plus" - call_endpoint "balances" "aggregator_total_wire_out_delta_minus" - - jq -e .wire_out_inconsistency[0] \ - < ${MY_TMP_DIR}/wire-out-inconsistency.json \ - > /dev/null \ - || exit_fail "Wire out inconsistency not detected" - - ROW=$(jq .wire_out_inconsistency[0].row_id < ${MY_TMP_DIR}/wire-out-inconsistency.json) - if [ "$ROW" != 1 ] - then - exit_fail "Row wrong" - fi - - AMOUNT=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/aggregator_total_wire_out_delta_plus.json) - if [ "$AMOUNT" != "TESTKUDOS:0" ] - then - exit_fail "Reported amount wrong: $AMOUNT" - fi - AMOUNT=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/aggregator_total_wire_out_delta_minus.json) - if [ "$AMOUNT" != "TESTKUDOS:0.01" ] - then - exit_fail "Reported total amount wrong: $AMOUNT" - fi - echo "PASS" + check_report \ + "wire-out-inconsistency" \ + "suppressed" "false" + echo -n "Testing inconsistency row report... " + check_report \ + "wire-out-inconsistency" \ + "wire_out_row_id" "1" + echo -n "Testing inconsistency balance... " + check_balance \ + "aggregation_total_wire_out_delta_plus" \ + "TESTKUDOS:0" \ + "Reported aggregation_total_wire_out_delta_plus wrong" + echo -n "Testing inconsistency balance change ... " + check_balance \ + "aggregation_total_wire_out_delta_minus" \ + "TESTKUDOS:0.01" \ + "Reported aggregation_total_wire_out_delta_minus wrong" echo "Second pass: changing how amount is wrong to other direction" NEW_AMOUNT=$(( OLD_AMOUNT + 1000000 )) @@ -1804,39 +1645,34 @@ function test_23() { audit_only post_audit - call_endpoint "balances" "aggregator_total_wire_out_delta_plus" - call_endpoint "balances" "aggregator_total_wire_out_delta_minus" - echo -n "Testing inconsistency detection... " - jq -e .wire_out_inconsistencies[0] < ${MY_TMP_DIR}/test-audit-aggregation.out > /dev/null || exit_fail "Wire out inconsistency not detected" - - ROW=$(jq .wire_out_inconsistencies[0].rowid < ${MY_TMP_DIR}/test-audit-aggregation.out) - if [ "$ROW" != 1 ] - then - exit_fail "Row wrong" - fi - AMOUNT=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/aggregator_total_wire_out_delta_minus.json) - if [ "$AMOUNT" != "TESTKUDOS:0" ] - then - exit_fail "Reported amount wrong: $AMOUNT" - fi - AMOUNT=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/aggregator_total_wire_out_delta_plus.json) - if [ "$AMOUNT" != "TESTKUDOS:0.01" ] - then - exit_fail "Reported total amount wrong: $AMOUNT" - fi - echo "PASS" + echo -n "Testing inconsistency detection... " + check_report \ + "wire-out-inconsistency" \ + "suppressed" "false" + echo -n "Testing inconsistency row report... " + check_report \ + "wire-out-inconsistency" \ + "wire_out_row_id" "1" + echo -n "Testing inconsistency balance... " + check_balance \ + "aggregation_total_wire_out_delta_plus" \ + "TESTKUDOS:0.01" \ + "Reported aggregation_total_wire_out_delta_plus wrong" + echo -n "Testing inconsistency balance change ... " + check_balance \ + "aggregation_total_wire_out_delta_minus" \ + "TESTKUDOS:0" \ + "Reported aggregation_total_wire_out_delta_minus wrong" # cannot easily undo aggregator, hence full reload full_reload - stop_auditor_httpd } # Test for missing deposits in exchange database. function test_24() { -#TODO needs to be rebuild probably echo "===========24: deposits missing ===========" # Modify denom_sig, so it is wrong CNT=$(echo "SELECT COUNT(*) FROM auditor.auditor_deposit_confirmations;" | psql -Aqt "$DB") @@ -1852,28 +1688,15 @@ function test_24() { check_auditor_running echo -n "Testing inconsistency detection... " - - call_endpoint "deposit-confirmation" call_endpoint "balances" - - jq -e .deposit_confirmation_inconsistencies[0] \ - < test-audit-deposits.json \ - > /dev/null \ - || exit_fail "Deposit confirmation inconsistency NOT detected" - - AMOUNT=$(jq -er .missing_deposit_confirmation_total < test-audit-deposits.json) - if [ "$AMOUNT" = "TESTKUDOS:0" ] - then - exit_fail "Expected non-zero total missing deposit confirmation amount" - fi - COUNT=$(jq -er .missing_deposit_confirmation_count < test-audit-deposits.json) - if [ "$AMOUNT" = "0" ] - then - exit_fail "Expected non-zero total missing deposit confirmation count" - fi - - echo "PASS" - + check_report \ + "deposit-confirmation" \ + "suppressed" "false" + echo -n "Testing inconsistency detection balance change ... " + check_not_balance \ + "total_missed_deposit_confirmations" \ + "TESTKUDOS:0" \ + "Expected non-zero total missing deposit confirmation amount" # cannot easily undo DELETE, hence full reload full_reload fi @@ -1881,6 +1704,7 @@ function test_24() { # Test for inconsistent coin history. +# FIXME: test-25 not implemented function test_25() { echo "=========25: inconsistent coin history=========" @@ -1896,30 +1720,30 @@ function test_25() { call_endpoint "coin-inconsistency" call_endpoint "emergency" - call_endpoint "balances" "aggregator_total_coin_delta_minus" call_endpoint "balances" "coins_reported_emergency_risk_by_amount" #TODO: doesn't find any #jq -e .coin_inconsistency[0] \ - # < ${MY_TMP_DIR}/coin-inconsistency.json \ + # < "${MY_TMP_DIR}/coin-inconsistency.json" \ # > /dev/null \ # || exit_fail "Coin inconsistency NOT detected" # Note: if the wallet withdrew much more than it spent, this might indeed # go legitimately unnoticed. #jq -e .emergency[0] \ - # < ${MY_TMP_DIR}/emergency.json \ + # < "${MY_TMP_DIR}/emergency.json" \ # > /dev/null \ # || exit_fail "Denomination value emergency NOT reported" #TODO: find's only wrong amount - #AMOUNT=$(jq -er .balances[0].balance_value < ${MY_TMP_DIR}/aggregator_total_coin_delta_minus.json) + call_endpoint "balances" "aggregation_total_coin_delta_minus" + #AMOUNT=$(jq -er .balances[0].balance_value < "${MY_TMP_DIR}/aggregation_total_coin_delta_minus.json") #if [ "$AMOUNT" = "TESTKUDOS:0" ] #then # exit_fail "Expected non-zero total inconsistency amount from coins" #fi # Note: if the wallet withdrew much more than it spent, this might indeed # go legitimately unnoticed. - #COUNT=$(jq -er .balances[0].balance_value < ${MY_TMP_DIR}/coins_reported_emergency_risk_by_amount.json) + #COUNT=$(jq -er .balances[0].balance_value < "${MY_TMP_DIR}/coins_reported_emergency_risk_by_amount.json") #if [ "$COUNT" = "TESTKUDOS:0" ] #then # exit_fail "Expected non-zero emergency-by-amount" @@ -1928,11 +1752,11 @@ function test_25() { # cannot easily undo DELETE, hence full reload full_reload - stop_auditor_httpd } # Test for deposit wire target malformed +# FIXME: test-26 not implemented function test_26() { echo "===========26: deposit wire target malformed =================" #TODO needs to be rebuild @@ -1953,25 +1777,25 @@ function test_26() { # # jq -e .bad_sig_losses[0] < test-audit-coins.json > /dev/null || exit_fail "Bad signature not detected" # -# ROW=$(jq -e .bad_sig_losses[0].row < test-audit-coins.json) +# ROW=$(jq -e .bad_sig_losses[0].row < test-audit-coins.json") # if [ "$ROW" != "${SERIAL}" ] # then # exit_fail "Row wrong, got $ROW" # fi # -# LOSS=$(jq -r .bad_sig_losses[0].loss < test-audit-coins.json) +# LOSS=$(jq -r .bad_sig_losses[0].loss < test-audit-coins.json") # if [ "$LOSS" != "TESTKUDOS:3" ] # then # exit_fail "Wrong deposit bad signature loss, got $LOSS" # fi # -# OP=$(jq -r .bad_sig_losses[0].operation < test-audit-coins.json) +# OP=$(jq -r .bad_sig_losses[0].operation < test-audit-coins.json") # if [ "$OP" != "deposit" ] # then # exit_fail "Wrong operation, got $OP" # fi # -# LOSS=$(jq -r .irregular_loss < test-audit-coins.json) +# LOSS=$(jq -r .irregular_loss < test-audit-coins.json") # if [ "$LOSS" != "TESTKUDOS:3" ] # then # exit_fail "Wrong total bad sig loss, got $LOSS" @@ -1984,6 +1808,7 @@ function test_26() { } # Test for duplicate wire transfer subject +# FIXME: test-27 not implemented function test_27() { echo "===========27: duplicate WTID detection =================" #TODO libeufin fix @@ -1996,7 +1821,7 @@ function test_27() { # # point to any record. That's only needed to set a non null value. # echo -e "INSERT INTO PaymentInitiations (\"bankAccount\",\"preparationDate\",\"submissionDate\",sum,currency,\"endToEndId\",\"paymentInformationId\",\"instructionId\",subject,\"creditorIban\",\"creditorBic\",\"creditorName\",submitted,\"messageId\",\"rawConfirmation\") VALUES (1,$(date +%s),$(( $(date +%s) + 2)),10,'TESTKUDOS','NOTGIVEN','unused','unused','$WTID http://exchange.example.com/','$OTHER_IBAN','SANDBOXX','Forty Two',false,1,2)" \ # | psql "${DB}" -q - # echo -e "INSERT INTO TalerRequestedPayments (facade,payment,\"requestUid\",amount,\"exchangeBaseUrl\",wtid,\"creditAccount\") VALUES (1,2,'unused','TESTKUDOS:1','http://exchange.example.com/','$WTID','payto://iban/SANDBOXX/$OTHER_IBAN?receiver-name=Forty+Two')" \ + # echo -e "INSERT INTO TalerRequestedPayments (facade,payment,\"requestUid\",amount,\"exchangeBaseUrl\",wtid,\"creditAccount\") VALUES (1,2,'unused','TESTKUDOS:1','http://exchange.example.com/','$WTID','payto://iban/$OTHER_IBAN?receiver-name=Forty+Two')" \ # | psql "${DB}" -q # launch_libeufin # audit_only @@ -2004,18 +1829,12 @@ function test_27() { # # echo -n "Testing inconsistency detection... " # - # AMOUNT=$(jq -r .wire_format_inconsistencies[0].amount < test-audit-wire.json) + # AMOUNT=$(jq -r .wire_format_inconsistencies[0].amount < test-audit-wire.json") # if [ "${AMOUNT}" != "TESTKUDOS:1" ] # then # exit_fail "Amount wrong, got ${AMOUNT}" # fi -# - # AMOUNT=$(jq -r .total_wire_format_amount < test-audit-wire.json) - # if [ "${AMOUNT}" != "TESTKUDOS:1" ] - # then - # exit_fail "Wrong total wire format amount, got $AMOUNT" - # fi -# + # # # cannot easily undo aggregator, hence full reload # full_reload } @@ -2038,39 +1857,26 @@ function test_28() { run_audit aggregator check_auditor_running - call_endpoint "bad-sig-losses" - call_endpoint "row-inconsistency" - call_endpoint "balances" "aggregator_total_bad_sig_loss" - echo -n "Testing inconsistency detection... " - LOSS=$(jq -r .bad_sig_losses[0].loss < ${MY_TMP_DIR}/bad-sig-losses.json) - if [ "$LOSS" == "TESTKUDOS:0" ] - then - exit_fail "Wrong deposit bad signature loss, got $LOSS" - fi + check_report_neg \ + "bad-sig-losses" \ + "loss" "TESTKUDOS:0" + echo -n "Testing inconsistency detection operation attribution... " + check_report \ + "bad-sig-losses" \ + "operation" "wire" + echo -n "Testing table attribution for inconsistency... " + check_report \ + "row-inconsistency" \ + "row_table" "deposit" + echo -n "Check signature loss was accumulated ..." + check_not_balance \ + "aggregation_total_bad_sig_loss" \ + "TESTKUDOS:0" \ + "Wrong aggregation_total_bad_sig_loss" - OP=$(jq -r .bad_sig_losses[0].operation < ${MY_TMP_DIR}/bad-sig-losses.json) - if [ "$OP" != "wire" ] - then - exit_fail "Wrong operation, got $OP" - fi - TAB=$(jq -r .row_inconsistency[0].row_table < ${MY_TMP_DIR}/row-inconsistency.json) - if [ "$TAB" != "deposit" ] - then - exit_fail "Wrong table for row inconsistency, got $TAB" - fi - - #TODO test seems to be wrong, original auditor logic seems to not spot it - #LOSS=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/total_bad_sig_loss.json) - #if [ "$LOSS" == "TESTKUDOS:0" ] - #then - # exit_fail "Wrong total bad sig loss, got $LOSS" - #fi - - echo "OK" # cannot easily undo aggregator, hence full reload full_reload - stop_auditor_httpd } @@ -2085,27 +1891,18 @@ function test_29() { run_audit check_auditor_running - call_endpoint "balances" "total_balance_summary_delta_minus" - call_endpoint "amount-arithmetic-inconsistency" - echo -n "Testing inconsistency detection... " - AMOUNT=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/total_balance_summary_delta_minus.json) - if [ "$AMOUNT" == "TESTKUDOS:0" ] - then - exit_fail "Reported total amount wrong: $AMOUNT" - fi - - PROFIT=$(jq -r .amount_arithmetic_inconsistency[0].profitable < ${MY_TMP_DIR}/amount-arithmetic-inconsistency.json) - if [ "$PROFIT" != "true" ] - then - exit_fail "Reported wrong profitability: $PROFIT" - fi - echo "OK" + check_not_balance \ + "total_balance_summary_delta_minus" \ + "TESTKUDOS:0" \ + "Reported total amount wrong" + echo -n "Checking report that delta was profitable... " + check_report \ + "amount-arithmetic-inconsistency" \ + "profitable" "true" # Undo echo "UPDATE exchange.denominations SET fee_withdraw.frac=2000000 WHERE (coin).val=1;" | psql -Aqt "$DB" full_reload - stop_auditor_httpd - } @@ -2119,38 +1916,27 @@ function test_30() { run_audit check_auditor_running - call_endpoint "bad-sig-losses" - call_endpoint "amount-arithmetic-inconsistency" - call_endpoint "emergency" - echo -n "Testing inconsistency detection... " - AMOUNT=$(jq -r .bad_sig_losses[0].loss < ${MY_TMP_DIR}/bad-sig-losses.json) - if [ "$AMOUNT" == "TESTKUDOS:0" ] - then - exit_fail "Reported total amount wrong: $AMOUNT" - fi + check_report_neg \ + "bad-sig-losses" \ + "loss" "TESTKUDOS:0" + echo -n "Testing inconsistency was reported as profitable... " + check_report \ + "amount-arithmetic-inconsistency" \ + "profitable" "true" + echo -n "Testing no emergency was raised... " + check_no_report "emergency" - PROFIT=$(jq -r .amount_arithmetic_inconsistency[0].profitable < ${MY_TMP_DIR}/amount-arithmetic-inconsistency.json) - if [ "$PROFIT" != "true" ] - then - exit_fail "Reported profitability wrong: $PROFIT" - fi - - jq -e .emergency[0] < ${MY_TMP_DIR}/emergency.json > /dev/null && exit_fail "Unexpected emergency detected in ordinary run" - echo "OK" # Undo echo "UPDATE exchange.denominations SET fee_refresh.frac=3000000 WHERE (coin).val=10;" | psql -Aqt "$DB" full_reload - stop_auditor_httpd - } # Test where fees known to the auditor differ from those # accounted for by the exchange function test_31() { - echo "===========31: deposit fee inconsistency =================" echo "UPDATE exchange.denominations SET fee_deposit.frac=5000000 WHERE (coin).val=8;" | psql -Aqt "$DB" @@ -2160,26 +1946,15 @@ function test_31() { echo -n "Testing inconsistency detection... " - call_endpoint "balances" "coin_irregular_loss" - call_endpoint "bad-sig-losses" - - AMOUNT=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/coin_irregular_loss.json) - if [ "$AMOUNT" == "TESTKUDOS:0" ] - then - exit_fail "Reported total amount wrong: $AMOUNT" - fi - - OP=$(jq -r --arg dep "deposit" '.bad_sig_losses[] | select(.operation == $dep) | .operation'< \ - ${MY_TMP_DIR}/bad-sig-losses.json | head -n1) - if [ "$OP" != "deposit" ] - then - exit_fail "Reported wrong operation: $OP" - fi - - echo "OK" + check_not_balance \ + "coin_irregular_loss" \ + "TESTKUDOS:0" \ + "Reported total coin_irregular_loss wrong" + check_report \ + "bad-sig-losses" \ + "operation" "deposit" # Undo echo "UPDATE exchange.denominations SET fee_deposit.frac=2000000 WHERE (coin).val=8;" | psql -Aqt "$DB" - stop_auditor_httpd full_reload } @@ -2189,7 +1964,6 @@ function test_31() { # Test where denom_sig in known_coins table is wrong # (=> bad signature) function test_32() { - echo "===========32: known_coins signature wrong w. aggregation=================" # Modify denom_sig, so it is wrong OLD_SIG=$(echo 'SELECT denom_sig FROM exchange.known_coins LIMIT 1;' | psql "$DB" -Aqt) @@ -2202,187 +1976,211 @@ function test_32() { check_auditor_running echo -n "Testing inconsistency detection... " + check_report \ + "bad-sig-losses" \ + "operation" "wire" + echo -n "Testing inconsistency balance update... " + check_not_balance \ + "aggregation_total_bad_sig_loss" \ + "TESTKUDOS:0" \ + "Missed updating aggregation_total_bad_sig_loss" - call_endpoint "bad-sig-losses" - - AMOUNT=$(jq -r .total_bad_sig_loss < ${MY_TMP_DIR}/bad-sig-losses.json) - if [ "$AMOUNT" == "TESTKUDOS:0" ] - then - exit_fail "Reported total amount wrong: $AMOUNT" - fi - - OP=$(jq -r .bad_sig_losses[0].operation < ${MY_TMP_DIR}/bad-sig-losses.json) - if [ "$OP" != "wire" ] - then - exit_fail "Reported wrong operation: $OP" - fi - - echo "OK" # Cannot undo aggregation, do full reload - stop_auditor_httpd full_reload cleanup } - function test_33() { echo "===========33: normal run with aggregator and profit drain===========" run_audit aggregator drain check_auditor_running - call_endpoint "emergency" - call_endpoint "deposit-confirmation" - call_endpoint "emergency-by-count" - call_endpoint "bad-sig-losses" - call_endpoint "balances" "coin_irregular_loss" - call_endpoint "balances" "aggregator_total_bad_sig_loss" - call_endpoint "balances" "reserves_total_bad_sig_loss" - call_endpoint "balances" "aggregator_total_arithmetic_delta_plus" - call_endpoint "balances" "aggregator_total_arithmetic_delta_minus" - call_endpoint "balances" "coins_total_arithmetic_delta_plus" - call_endpoint "balances" "coins_total_arithmetic_delta_minus" - call_endpoint "balances" "reserves_total_arithmetic_delta_plus" - call_endpoint "balances" "reserves_total_arithmetic_delta_minus" - call_endpoint "balances" - call_endpoint "amount-arithmetic-inconsistency" - call_endpoint "wire-out-inconsistency" - echo "Checking output" # if an emergency was detected, that is a bug and we should fail echo -n "Test for emergencies... " - jq -e .emergency[0] < ${MY_TMP_DIR}/emergency.json > /dev/null && exit_fail "Unexpected emergency detected in ordinary run" || echo PASS - echo -n "Test for deposit confirmation emergencies... " - jq -e .deposit_confirmation[0] < ${MY_TMP_DIR}/deposit-confirmation.json > /dev/null && exit_fail "Unexpected deposit confirmation inconsistency detected" || echo PASS + check_no_report "emergency" + echo -n "Test for deposit confirmation detection... " + check_no_report "deposit-confirmation" echo -n "Test for emergencies by count... " - jq -e .emergency_by_count[0] < ${MY_TMP_DIR}/emergency-by-count.json > /dev/null && exit_fail "Unexpected emergency by count detected in ordinary run" || echo PASS - - echo -n "Test for wire inconsistencies... " - #TODO: fix wire - #jq -e .wire_out_amount_inconsistencies[0] < test-audit-wire.json > /dev/null && exit_fail "Unexpected wire out inconsistency detected in ordinary run" - #jq -e .reserve_in_amount_inconsistencies[0] < test-audit-wire.json > /dev/null && exit_fail "Unexpected reserve in inconsistency detected in ordinary run" - #jq -e .misattribution_inconsistencies[0] < test-audit-wire.json > /dev/null && exit_fail "Unexpected misattribution inconsistency detected in ordinary run" - #jq -e .row_inconsistencies[0] < test-audit-wire.json > /dev/null && exit_fail "Unexpected row inconsistency detected in ordinary run" - #jq -e .denomination_key_validity_withdraw_inconsistencies[0] < test-audit-reserves.json > /dev/null && exit_fail "Unexpected denomination key withdraw inconsistency detected in ordinary run" - #jq -e .row_minor_inconsistencies[0] < test-audit-wire.json > /dev/null && exit_fail "Unexpected minor row inconsistency detected in ordinary run" - #jq -e .lag_details[0] < test-audit-wire.json > /dev/null && exit_fail "Unexpected lag detected in ordinary run" - #jq -e .wire_format_inconsistencies[0] < test-audit-wire.json > /dev/null && exit_fail "Unexpected wire format inconsistencies detected in ordinary run" - - - # TODO: check operation balances are correct (once we have all transaction types and wallet is deterministic) - # TODO: check revenue summaries are correct (once we have all transaction types and wallet is deterministic) + check_no_report "emergency-by-count" + + echo -n "Testing bad sig loss balance... " + check_balance \ + "aggregation_total_bad_sig_loss" \ + "TESTKUDOS:0" \ + "Wrong total bad sig loss from aggregation, got unexpected loss" + + echo -n "Testing coin irregular loss balances... " + check_balance \ + "coin_irregular_loss" \ + "TESTKUDOS:0" \ + "Wrong total bad sig loss from coins" + + echo -n "Testing reserves bad sig loss balances... " + check_balance \ + "reserves_total_bad_sig_loss" \ + "TESTKUDOS:0" \ + "Wrong total bad sig loss from reserves" + + echo -n "Test for aggregation wire out delta plus... " + check_balance \ + "aggregation_total_wire_out_delta_plus" \ + "TESTKUDOS:0" \ + "Expected total wire out delta plus wrong" + + echo -n "Test for aggregation wire out delta minus... " + check_balance \ + "aggregation_total_wire_out_delta_minus" \ + "TESTKUDOS:0" \ + "Expected total wire out delta minus wrong" + + echo -n "Test for bad incoming delta plus... " + check_balance \ + "total_bad_amount_in_plus" \ + "TESTKUDOS:0" \ + "Expected total wire in delta plus wrong" + + echo -n "Test for total misattribution in ... " + check_balance \ + "total_misattribution_in" \ + "TESTKUDOS:0" \ + "Expected total wire in delta plus wrong" + + echo -n "Test for bad incoming delta minus... " + check_balance \ + "total_bad_amount_in_minus" \ + "TESTKUDOS:0" \ + "Expected total wire in delta minus wrong" + + echo -n "Test for bad outgoing delta plus... " + check_balance \ + "total_bad_amount_out_plus" \ + "TESTKUDOS:0" \ + "Expected total wire out delta plus wrong" + + echo -n "Test for bad outgoing delta minus... " + check_balance \ + "total_bad_amount_out_minus" \ + "TESTKUDOS:0" \ + "Expected total wire in delta minus wrong" + + echo -n "Test for misattribution amounts... " + check_balance \ + "total_misattribution_in" \ + "TESTKUDOS:0" \ + "Expected total misattribution in wrong" + + echo -n "Checking for unexpected aggregation delta plus differences... " + check_balance \ + "aggregation_total_arithmetic_delta_plus" \ + "TESTKUDOS:0" \ + "Wrong arithmetic delta plus from aggregations" + + echo -n "Checking for unexpected aggregation delta minus differences... " + check_balance \ + "aggregation_total_arithmetic_delta_minus" \ + "TESTKUDOS:0" \ + "Wrong arithmetic delta minus from aggregations" + + echo -n "Checking for unexpected coin delta plus differences... " + check_balance \ + "coins_total_arithmetic_delta_plus" \ + "TESTKUDOS:0" \ + "Wrong arithmetic delta plus from coins" + + echo -n "Checking for unexpected coin delta minus differences... " + check_balance \ + "coins_total_arithmetic_delta_minus" \ + "TESTKUDOS:0" \ + "Wrong arithmetic delta minus from coins" + + echo -n "Checking for unexpected reserves delta plus... " + check_balance \ + "reserves_total_arithmetic_delta_plus" \ + "TESTKUDOS:0" \ + "Wrong arithmetic delta plus from reserves" + + echo -n "Checking for unexpected reserves delta minus... " + check_balance \ + "reserves_total_arithmetic_delta_minus" \ + "TESTKUDOS:0" \ + "Wrong arithmetic delta minus from reserves" - echo PASS - - LOSS=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/aggregator_total_bad_sig_loss.json) - if [ "$LOSS" != "TESTKUDOS:0" ] - then - exit_fail "Wrong total bad sig loss from aggregation, got unexpected loss of $LOSS" - fi - LOSS=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/coin_irregular_loss.json) - if [ "$LOSS" != "TESTKUDOS:0" ] - then - exit_fail "Wrong total bad sig loss from coins, got unexpected loss of $LOSS" - fi - LOSS=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/reserves_total_bad_sig_loss.json) - if [ "$LOSS" != "TESTKUDOS:0" ] - then - exit_fail "Wrong total bad sig loss from reserves, got unexpected loss of $LOSS" - fi - - echo -n "Test for wire amounts... " - #WIRED=$(jq -r .total_wire_in_delta_plus < test-audit-wire.json) - #if [ "$WIRED" != "TESTKUDOS:0" ] - #then - # exit_fail "Expected total wire delta plus wrong, got $WIRED" - #fi - #WIRED=$(jq -r .total_wire_in_delta_minus < test-audit-wire.json) - #if [ "$WIRED" != "TESTKUDOS:0" ] - #then - # exit_fail "Expected total wire delta minus wrong, got $WIRED" - #fi - #WIRED=$(jq -r .total_wire_out_delta_plus < test-audit-wire.json) - #if [ "$WIRED" != "TESTKUDOS:0" ] - #then - # exit_fail "Expected total wire delta plus wrong, got $WIRED" - #fi - #WIRED=$(jq -r .total_wire_out_delta_minus < test-audit-wire.json) - #if [ "$WIRED" != "TESTKUDOS:0" ] - #then - # exit_fail "Expected total wire delta minus wrong, got $WIRED" - #fi - #WIRED=$(jq -r .total_misattribution_in < test-audit-wire.json) - #if [ "$WIRED" != "TESTKUDOS:0" ] - #then - # exit_fail "Expected total misattribution in wrong, got $WIRED" - #fi - echo PASS - - echo -n "Checking for unexpected arithmetic differences " - LOSS=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/aggregator_total_arithmetic_delta_plus.json) - if [ "$LOSS" != "TESTKUDOS:0" ] - then - exit_fail "Wrong arithmetic delta from aggregations, got unexpected plus of $LOSS" - fi - LOSS=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/aggregator_total_arithmetic_delta_minus.json) - if [ "$LOSS" != "TESTKUDOS:0" ] - then - exit_fail "Wrong arithmetic delta from aggregation, got unexpected minus of $LOSS" - fi - LOSS=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/coins_total_arithmetic_delta_plus.json) - if [ "$LOSS" != "TESTKUDOS:0" ] - then - exit_fail "Wrong arithmetic delta from coins, got unexpected plus of $LOSS" - fi - LOSS=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/coins_total_arithmetic_delta_minus.json) - if [ "$LOSS" != "TESTKUDOS:0" ] - then - exit_fail "Wrong arithmetic delta from coins, got unexpected minus of $LOSS" - fi - LOSS=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/reserves_total_arithmetic_delta_plus.json) - if [ "$LOSS" != "TESTKUDOS:0" ] - then - exit_fail "Wrong arithmetic delta from reserves, got unexpected plus of $LOSS" - fi - LOSS=$(jq -r .balances[0].balance_value < ${MY_TMP_DIR}/reserves_total_arithmetic_delta_minus.json) - if [ "$LOSS" != "TESTKUDOS:0" ] - then - exit_fail "Wrong arithmetic delta from reserves, got unexpected minus of $LOSS" - fi + echo -n "Checking for unexpected wire out differences " + check_no_report "wire-out-inconsistency" - #DRAINED=$(jq -r .total_drained < test-audit-wire.json) - #if [ "$DRAINED" != "TESTKUDOS:0.1" ] - #then - # exit_fail "Wrong amount drained, got unexpected drain of $DRAINED" - #fi + # Just to test the endpoint and for logging ... + call_endpoint "balances" -#TODO: fix AAI -# jq -e .amount_arithmetic_inconsistency[0] \ -# < ${MY_TMP_DIR}/amount-arithmetic-inconsistency.json \ -# > /dev/null \ -# && exit_fail "Unexpected arithmetic inconsistencies from aggregations detected in ordinary run" -# jq -e .amount_arithmetic_inconsistency[0] \ -# < ${MY_TMP_DIR}/amount-arithmetic-inconsistency.json \ -# > /dev/null \ -# && exit_fail "Unexpected arithmetic inconsistencies from coins detected in ordinary run" -# jq -e .amount_arithmetic_inconsistency[0] \ -# < ${MY_TMP_DIR}/amount-arithmetic-inconsistency.json \ -# > /dev/null \ -# && exit_fail "Unexpected arithmetic inconsistencies from reserves detected in ordinary run" - echo "PASS" + echo -n "Testing for aggregation bad sig loss" + check_balance \ + "aggregation_total_bad_sig_loss" \ + "TESTKUDOS:0" \ + "Wrong total bad sig loss from aggregation, got unexpected loss" + + echo -n "Testing for coin bad sig loss" + check_balance \ + "coin_irregular_loss" \ + "TESTKUDOS:0" \ + "Wrong total bad sig loss from coins, got unexpected loss" + + echo -n "Testing for reserves bad sig loss" + check_balance \ + "reserves_total_bad_sig_loss" \ + "TESTKUDOS:0" \ + "Wrong total bad sig loss from reserves, got unexpected loss" + + echo -n "Checking for unexpected aggregation delta plus differences... " + check_balance \ + "aggregation_total_arithmetic_delta_plus" \ + "TESTKUDOS:0" \ + "Wrong arithmetic delta plus from aggregations" + + echo -n "Checking for unexpected aggregation delta minus differences... " + check_balance \ + "aggregation_total_arithmetic_delta_minus" \ + "TESTKUDOS:0" \ + "Wrong arithmetic delta minus from aggregations" + + echo -n "Checking for unexpected coin delta plus differences... " + check_balance \ + "coins_total_arithmetic_delta_plus" \ + "TESTKUDOS:0" \ + "Wrong arithmetic delta plus from coins" + + echo -n "Checking for unexpected coin delta minus differences... " + check_balance \ + "coins_total_arithmetic_delta_minus" \ + "TESTKUDOS:0" \ + "Wrong arithmetic delta minus from coins" + + echo -n "Checking for unexpected reserves delta plus... " + check_balance \ + "reserves_total_arithmetic_delta_plus" \ + "TESTKUDOS:0" \ + "Wrong arithmetic delta plus from reserves" + + echo -n "Checking for unexpected reserves delta minus... " + check_balance \ + "reserves_total_arithmetic_delta_minus" \ + "TESTKUDOS:0" \ + "Wrong arithmetic delta minus from reserves" + + echo -n "Checking amount arithmetic inconsistency" + check_no_report "amount-arithmetic-inconsistency" echo -n "Checking for unexpected wire out differences " - jq -e .wire_out_inconsistency[0] \ - < ${MY_TMP_DIR}/wire-out-inconsistency.json \ - > /dev/null \ - && exit_fail "Unexpected wire out inconsistencies detected in ordinary run" - echo "PASS" + check_no_report "wire-out-inconsistency" + echo -n "Checking total drained... " + check_balance \ + "total_drained" \ + "TESTKUDOS:0.1" \ + "Wrong total drained amount reported" # cannot easily undo aggregator, hence full reload full_reload - stop_auditor_httpd - } @@ -2395,6 +2193,7 @@ function check_with_database() { BASEDB="$1" CONF="$1.conf" + export CONF echo "Running test suite with database $BASEDB using configuration $CONF" MASTER_PRIV_FILE="${BASEDB}.mpriv" taler-config \ @@ -2525,6 +2324,8 @@ then echo "Generation failed" exit 1 fi + echo "To reuse this database in the future, use:" + echo "export REUSE_BASEDB_DIR=$MY_TMP_DIR" else echo "Reusing existing database from ${REUSE_BASEDB_DIR}" cp -r "${REUSE_BASEDB_DIR}/basedb"/* "${MYDIR}/" @@ -2536,7 +2337,7 @@ then exit "$fail" fi -if [ -z "${REUSE_BASEDB_DIR}" ] +if [ -z "${REUSE_BASEDB_DIR+x}" ] then echo "Run 'export REUSE_BASEDB_DIR=${MY_TMP_DIR}' to re-run tests against the same database" fi diff --git a/src/auditor/test-kyc.sh b/src/auditor/test-kyc.sh index 2c4fa6594..f90350184 100755 --- a/src/auditor/test-kyc.sh +++ b/src/auditor/test-kyc.sh @@ -342,7 +342,7 @@ function run_audit () { -L DEBUG \ -c "${CONF}" \ drain TESTKUDOS:0.1 \ - exchange-account-1 payto://iban/SANDBOXX/DE360679?receiver-name=Exchange+Drain \ + exchange-account-1 payto://iban/DE360679?receiver-name=Exchange+Drain \ upload \ 2> "${MY_TMP_DIR}/taler-exchange-offline-drain.log" \ || exit_fail "offline draining failed" @@ -356,18 +356,18 @@ function run_audit () { 2> "${MY_TMP_DIR}/taler-exchange-drain.log" \ || exit_fail "FAIL" echo " DONE" + fi + echo -n "Running taler-exchange-transfer ..." + taler-exchange-transfer \ + -L INFO \ + -t \ + -c "$CONF" \ + 2> "${MY_TMP_DIR}/drain-transfer.log" \ + || exit_fail "FAIL" + echo " DONE" - echo -n "Running taler-exchange-transfer ..." - taler-exchange-transfer \ - -L INFO \ - -t \ - -c "$CONF" \ - 2> "${MY_TMP_DIR}/drain-transfer.log" \ - || exit_fail "FAIL" - echo " DONE" - - audit_only - post_audit + audit_only + post_audit } diff --git a/src/auditor/test-sync.sh b/src/auditor/test-sync.sh index bcef908aa..de24ae764 100755 --- a/src/auditor/test-sync.sh +++ b/src/auditor/test-sync.sh @@ -71,7 +71,7 @@ function check_with_database() -d test-sync-out.conf -t # cs_nonce_locks excluded: no point - for table in denominations denomination_revocations wire_targets reserves reserves_in reserves_close reserves_out auditors auditor_denom_sigs exchange_sign_keys signkey_revocations extensions policy_details policy_fulfillments known_coins refresh_commitments refresh_revealed_coins refresh_transfer_keys deposits refunds wire_out aggregation_tracking wire_fee recoup recoup_refresh + for table in denominations denomination_revocations wire_targets reserves reserves_in reserves_close reserves_open_requests reserves_open_deposits reserves_out auditors auditor_denom_sigs exchange_sign_keys signkey_revocations known_coins refresh_commitments refresh_revealed_coins refresh_transfer_keys batch_deposits coin_deposits refunds wire_out aggregation_tracking wire_fee recoup recoup_refresh extensions policy_details policy_fulfillments purse_requests purse_decision purse_merges purse_deposits account_merges history_requests close_requests wads_out wad_out_entries wads_in wad_in_entries profit_Drains aml_staff purse_deletion age_withdraw legitimization_measures legitimization_outcomes legitimization_processes kyc_attributes aml_history kyc_events kycauths_in do echo -n "." CIN=$(echo "SELECT COUNT(*) FROM exchange.$table" | psql talercheck-in -Aqt) diff --git a/src/auditordb/0002-auditor_amount_arithmetic_inconsistency.sql b/src/auditordb/0002-auditor_amount_arithmetic_inconsistency.sql index 69b64bc41..8dcf7b742 100644 --- a/src/auditordb/0002-auditor_amount_arithmetic_inconsistency.sql +++ b/src/auditordb/0002-auditor_amount_arithmetic_inconsistency.sql @@ -14,17 +14,14 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- --- TODO: The constraints of operation are just for testing - CREATE TABLE auditor_amount_arithmetic_inconsistency ( - row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE, - -- TODO: correct constraintcheck, currently wrong - --operation BYTEA NOT NULL CHECK (LENGTH(operation)=16), - operation TEXT NOT NULL PRIMARY KEY, - exchange_amount taler_amount, - auditor_amount taler_amount, - profitable BOOLEAN, + row_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + problem_row_id BIGINT NOT NULL, + operation TEXT NOT NULL, + exchange_amount taler_amount NOT NULL, + auditor_amount taler_amount NOT NULL, + profitable BOOLEAN NOT NULL, suppressed BOOLEAN NOT NULL DEFAULT FALSE ); COMMENT ON TABLE auditor_amount_arithmetic_inconsistency diff --git a/src/auditordb/0002-auditor_bad_sig_losses.sql b/src/auditordb/0002-auditor_bad_sig_losses.sql index c5a222251..bcaaf4987 100644 --- a/src/auditordb/0002-auditor_bad_sig_losses.sql +++ b/src/auditordb/0002-auditor_bad_sig_losses.sql @@ -14,15 +14,14 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- -SET search_path TO auditor; CREATE TABLE IF NOT EXISTS auditor_bad_sig_losses ( - row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE, - operation TEXT, - loss taler_amount, + row_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + problem_row_id BIGINT NOT NULL, + operation TEXT NOT NULL, + loss taler_amount NOT NULL, operation_specific_pub BYTEA NOT NULL CHECK (LENGTH(operation_specific_pub)=32), - suppressed BOOLEAN NOT NULL DEFAULT FALSE, - PRIMARY KEY (operation, operation_specific_pub) + suppressed BOOLEAN NOT NULL DEFAULT FALSE ); COMMENT ON TABLE auditor_bad_sig_losses IS 'Report a (serious) inconsistency with losses due to bad signatures'; diff --git a/src/auditordb/0002-auditor_balances.sql b/src/auditordb/0002-auditor_balances.sql index 78ff8a414..e25c3049c 100644 --- a/src/auditordb/0002-auditor_balances.sql +++ b/src/auditordb/0002-auditor_balances.sql @@ -16,7 +16,7 @@ CREATE TABLE IF NOT EXISTS auditor_balances ( - row_id BIGINT GENERATED BY DEFAULT AS IDENTITY, + row_id BIGINT GENERATED BY DEFAULT AS IDENTITY, balance_key TEXT PRIMARY KEY NOT NULL, balance_value taler_amount diff --git a/src/auditordb/0002-auditor_closure_lags.sql b/src/auditordb/0002-auditor_closure_lags.sql index 93484f399..6822ef150 100644 --- a/src/auditordb/0002-auditor_closure_lags.sql +++ b/src/auditordb/0002-auditor_closure_lags.sql @@ -14,14 +14,14 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- -SET search_path TO auditor; CREATE TABLE IF NOT EXISTS auditor_closure_lags ( row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY, - amount taler_amount, - deadline BIGINT, - wtid BYTEA, - account BYTEA, + problem_row_id BIGINT NOT NULL, + amount taler_amount NOT NULL, + deadline BIGINT NOT NULL, + wtid BYTEA NOT NULL CHECK (LENGTH(wtid)=32), + account TEXT NOT NULL, suppressed BOOLEAN NOT NULL DEFAULT FALSE ); COMMENT ON TABLE auditor_closure_lags diff --git a/src/auditordb/0002-auditor_coin_inconsistency.sql b/src/auditordb/0002-auditor_coin_inconsistency.sql index ea5210d68..73ac1db13 100644 --- a/src/auditordb/0002-auditor_coin_inconsistency.sql +++ b/src/auditordb/0002-auditor_coin_inconsistency.sql @@ -14,17 +14,16 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- -SET search_path TO auditor; + CREATE TABLE IF NOT EXISTS auditor_coin_inconsistency ( - row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE, + row_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, operation TEXT NOT NULL, - exchange_amount taler_amount, - auditor_amount taler_amount, + exchange_amount taler_amount NOT NULL, + auditor_amount taler_amount NOT NULL, coin_pub BYTEA NOT NULL CHECK (LENGTH(coin_pub)=32), - profitable BOOLEAN, - suppressed BOOLEAN NOT NULL DEFAULT FALSE, - PRIMARY KEY (operation, coin_pub) + profitable BOOLEAN NOT NULL, + suppressed BOOLEAN NOT NULL DEFAULT FALSE ); COMMENT ON TABLE auditor_coin_inconsistency IS 'Report a (serious) inconsistency in the exchange''s database with respect to calculations involving amounts'; diff --git a/src/auditordb/0002-auditor_denomination_key_validity_withdraw_inconsistency.sql b/src/auditordb/0002-auditor_denomination_key_validity_withdraw_inconsistency.sql index 029bc90e0..6bde7400b 100644 --- a/src/auditordb/0002-auditor_denomination_key_validity_withdraw_inconsistency.sql +++ b/src/auditordb/0002-auditor_denomination_key_validity_withdraw_inconsistency.sql @@ -14,13 +14,13 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- -SET search_path TO auditor; CREATE TABLE IF NOT EXISTS auditor_denomination_key_validity_withdraw_inconsistency ( row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY, - execution_date BIGINT, - reserve_pub BYTEA, - denompub_h BYTEA, + problem_row_id BIGINT NOT NULL, + execution_date BIGINT NOT NULL, + reserve_pub BYTEA NOT NULL CHECK (LENGTH(reserve_pub)=32), + denompub_h BYTEA NOT NULL CHECK (LENGTH(denompub_h)=64), suppressed BOOLEAN NOT NULL DEFAULT FALSE ); COMMENT ON TABLE auditor_denomination_key_validity_withdraw_inconsistency diff --git a/src/auditordb/0002-auditor_denomination_pending.sql b/src/auditordb/0002-auditor_denomination_pending.sql index 00ed18145..2b1ee99a5 100644 --- a/src/auditordb/0002-auditor_denomination_pending.sql +++ b/src/auditordb/0002-auditor_denomination_pending.sql @@ -15,8 +15,8 @@ -- CREATE TABLE auditor_denomination_pending - (row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE, - denom_pub_hash BYTEA PRIMARY KEY CHECK (LENGTH(denom_pub_hash)=64) + (row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE + ,denom_pub_hash BYTEA PRIMARY KEY CHECK (LENGTH(denom_pub_hash)=64) ,denom_balance taler_amount NOT NULL ,denom_loss taler_amount NOT NULL ,num_issued BIGINT NOT NULL diff --git a/src/auditordb/0002-auditor_denominations_without_sigs.sql b/src/auditordb/0002-auditor_denominations_without_sigs.sql index 94ea0a351..abd7d981f 100644 --- a/src/auditordb/0002-auditor_denominations_without_sigs.sql +++ b/src/auditordb/0002-auditor_denominations_without_sigs.sql @@ -14,13 +14,12 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- -SET search_path TO auditor; CREATE TABLE IF NOT EXISTS auditor_denominations_without_sigs ( row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE, denompub_h BYTEA PRIMARY KEY, - value taler_amount, - start_time BIGINT, + value taler_amount NOT NULL, + start_time BIGINT NOT NULL, end_time BIGINT, suppressed BOOLEAN NOT NULL DEFAULT FALSE ); diff --git a/src/auditordb/0002-auditor_deposit_confirmations.sql b/src/auditordb/0002-auditor_deposit_confirmations.sql index 7e47b4fd1..c9541d603 100644 --- a/src/auditordb/0002-auditor_deposit_confirmations.sql +++ b/src/auditordb/0002-auditor_deposit_confirmations.sql @@ -15,24 +15,24 @@ -- CREATE TABLE auditor_deposit_confirmations -(deposit_confirmation_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE - ,h_contract_terms BYTEA NOT NULL CHECK (LENGTH(h_contract_terms)=64) - ,h_policy BYTEA NOT NULL CHECK (LENGTH(h_policy)=64) - ,h_wire BYTEA NOT NULL CHECK (LENGTH(h_wire)=64) - ,exchange_timestamp BIGINT NOT NULL - ,refund_deadline BIGINT NOT NULL - ,wire_deadline BIGINT NOT NULL - ,total_without_fee taler_amount NOT NULL - ,coin_pubs BYTEA[] NOT NULL CHECK (CARDINALITY(coin_pubs)>0) - ,coin_sigs BYTEA[] NOT NULL CHECK (CARDINALITY(coin_sigs)=CARDINALITY(coin_pubs)) - ,merchant_pub BYTEA NOT NULL CHECK (LENGTH(merchant_pub)=32) - ,exchange_sig BYTEA NOT NULL CHECK (LENGTH(exchange_sig)=64) - ,exchange_pub BYTEA NOT NULL CHECK (LENGTH(exchange_pub)=32) - ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64) - ,suppressed BOOLEAN NOT NULL DEFAULT FALSE - ,ancient BOOLEAN NOT NULL DEFAULT FALSE - ,PRIMARY KEY (h_contract_terms,h_wire,merchant_pub,exchange_sig,exchange_pub,master_sig) - ); + (row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE + ,h_contract_terms BYTEA NOT NULL CHECK (LENGTH(h_contract_terms)=64) + ,h_policy BYTEA NOT NULL CHECK (LENGTH(h_policy)=64) + ,h_wire BYTEA NOT NULL CHECK (LENGTH(h_wire)=64) + ,exchange_timestamp BIGINT NOT NULL + ,refund_deadline BIGINT NOT NULL + ,wire_deadline BIGINT NOT NULL + ,total_without_fee taler_amount NOT NULL + ,coin_pubs BYTEA[] NOT NULL CHECK (CARDINALITY(coin_pubs)>0) + ,coin_sigs BYTEA[] NOT NULL CHECK (CARDINALITY(coin_sigs)=CARDINALITY(coin_pubs)) + ,merchant_pub BYTEA NOT NULL CHECK (LENGTH(merchant_pub)=32) + ,exchange_sig BYTEA NOT NULL CHECK (LENGTH(exchange_sig)=64) + ,exchange_pub BYTEA NOT NULL CHECK (LENGTH(exchange_pub)=32) + ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64) + ,suppressed BOOLEAN NOT NULL DEFAULT FALSE + ,ancient BOOLEAN NOT NULL DEFAULT FALSE + ,PRIMARY KEY (h_contract_terms,h_wire,merchant_pub,exchange_sig,exchange_pub,master_sig) + ); COMMENT ON TABLE auditor_deposit_confirmations IS 'deposit confirmation sent to us by merchants; we must check that the exchange reported these properly.'; diff --git a/src/auditordb/0002-auditor_emergency.sql b/src/auditordb/0002-auditor_emergency.sql index 5fcd3cd06..90f0ca8b8 100644 --- a/src/auditordb/0002-auditor_emergency.sql +++ b/src/auditordb/0002-auditor_emergency.sql @@ -1,5 +1,3 @@ - - -- -- This file is part of TALER -- Copyright (C) 2014--2024 Taler Systems SA @@ -16,16 +14,16 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- -SET search_path TO auditor; CREATE TABLE IF NOT EXISTS auditor_emergency ( row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY, denompub_h BYTEA CHECK (LENGTH(denompub_h)=64), - denom_risk taler_amount, - denom_loss taler_amount, - deposit_start BIGINT, - deposit_end BIGINT, - value taler_amount + denom_risk taler_amount NOT NULL, + denom_loss taler_amount NOT NULL, + deposit_start BIGINT NOT NULL, + deposit_end BIGINT NOT NULL, + value taler_amount NOT NULL, + suppressed BOOLEAN NOT NULL DEFAULT FALSE ); COMMENT ON TABLE auditor_emergency IS 'Report an emergency denomination.'; diff --git a/src/auditordb/0002-auditor_emergency_by_count.sql b/src/auditordb/0002-auditor_emergency_by_count.sql index ff8ba405a..6d2be80aa 100644 --- a/src/auditordb/0002-auditor_emergency_by_count.sql +++ b/src/auditordb/0002-auditor_emergency_by_count.sql @@ -14,17 +14,16 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- -SET search_path TO auditor; CREATE TABLE IF NOT EXISTS auditor_emergency_by_count ( row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY, - denompub_h BYTEA, - num_issued BIGINT, - num_known BIGINT, - risk taler_amount, - start BIGINT, - deposit_end BIGINT, - value taler_amount, + denompub_h BYTEA NOT NULL CHECK (LENGTH(denompub_h)=64), + num_issued BIGINT NOT NULL, + num_known BIGINT NOT NULL, + risk taler_amount NOT NULL, + start BIGINT NOT NULL, + deposit_end BIGINT NOT NULL, + value taler_amount NOT NULL, suppressed BOOLEAN NOT NULL DEFAULT FALSE ); COMMENT ON TABLE auditor_emergency_by_count diff --git a/src/auditordb/0002-auditor_exchange_signkeys.sql b/src/auditordb/0002-auditor_exchange_signkeys.sql index 25aa13cad..207a51b61 100644 --- a/src/auditordb/0002-auditor_exchange_signkeys.sql +++ b/src/auditordb/0002-auditor_exchange_signkeys.sql @@ -15,8 +15,8 @@ -- CREATE TABLE auditor_exchange_signkeys - (row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE, - exchange_pub BYTEA PRIMARY KEY CHECK (LENGTH(exchange_pub)=32) + (row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE + ,exchange_pub BYTEA PRIMARY KEY CHECK (LENGTH(exchange_pub)=32) ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64) ,ep_valid_from BIGINT NOT NULL ,ep_expire_sign BIGINT NOT NULL diff --git a/src/auditordb/0002-auditor_fee_time_inconsistency.sql b/src/auditordb/0002-auditor_fee_time_inconsistency.sql index 1cea6caa6..c2ec60032 100644 --- a/src/auditordb/0002-auditor_fee_time_inconsistency.sql +++ b/src/auditordb/0002-auditor_fee_time_inconsistency.sql @@ -14,13 +14,13 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- -SET search_path TO auditor; CREATE TABLE IF NOT EXISTS auditor_fee_time_inconsistency ( row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY, - type BYTEA, - time BIGINT, - diagnostic BYTEA, + problem_row_id BIGINT NOT NULL, + fee_type TEXT NOT NULL, + fee_time BIGINT NOT NULL, + diagnostic TEXT NOT NULL, suppressed BOOLEAN NOT NULL DEFAULT FALSE ); COMMENT ON TABLE auditor_fee_time_inconsistency diff --git a/src/auditordb/0002-auditor_historic_denomination_revenue.sql b/src/auditordb/0002-auditor_historic_denomination_revenue.sql index d711ac7fc..a902fe456 100644 --- a/src/auditordb/0002-auditor_historic_denomination_revenue.sql +++ b/src/auditordb/0002-auditor_historic_denomination_revenue.sql @@ -15,8 +15,8 @@ -- CREATE TABLE auditor_historic_denomination_revenue - (row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE, - denom_pub_hash BYTEA PRIMARY KEY CHECK (LENGTH(denom_pub_hash)=64) + (row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE + ,denom_pub_hash BYTEA PRIMARY KEY CHECK (LENGTH(denom_pub_hash)=64) ,revenue_timestamp BIGINT NOT NULL ,revenue_balance taler_amount NOT NULL ,loss_balance taler_amount NOT NULL diff --git a/src/auditordb/0002-auditor_historic_reserve_summary.sql b/src/auditordb/0002-auditor_historic_reserve_summary.sql index 0dc68d594..742a59f32 100644 --- a/src/auditordb/0002-auditor_historic_reserve_summary.sql +++ b/src/auditordb/0002-auditor_historic_reserve_summary.sql @@ -14,16 +14,13 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- -SET search_path TO auditor; CREATE TABLE IF NOT EXISTS auditor_historic_reserve_summary ( row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE, - start_date BIGINT, + start_date BIGINT NOT NULL, end_date BIGINT NOT NULL, reserve_profits taler_amount NOT NULL, PRIMARY KEY (start_date, end_date) - - ); COMMENT ON TABLE auditor_historic_reserve_summary IS 'historic profits from reserves; we eventually GC auditor_historic_reserve_revenue, and then store the totals in here (by time intervals).'; diff --git a/src/auditordb/0002-auditor_misattribution_in_inconsistency.sql b/src/auditordb/0002-auditor_misattribution_in_inconsistency.sql index 48050412d..a351f7dfd 100644 --- a/src/auditordb/0002-auditor_misattribution_in_inconsistency.sql +++ b/src/auditordb/0002-auditor_misattribution_in_inconsistency.sql @@ -14,13 +14,13 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- -SET search_path TO auditor; + CREATE TABLE IF NOT EXISTS auditor_misattribution_in_inconsistency ( row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY, - amount taler_amount, - bank_row BIGINT, - reserve_pub BYTEA, + amount taler_amount NOT NULL, + bank_row BIGINT NOT NULL, + reserve_pub BYTEA NOT NULL CHECK (LENGTH(reserve_pub)=32), suppressed BOOLEAN NOT NULL DEFAULT FALSE ); COMMENT ON TABLE auditor_misattribution_in_inconsistency diff --git a/src/auditordb/0002-auditor_pending_deposits.sql b/src/auditordb/0002-auditor_pending_deposits.sql index 5cef7bf8c..4521bd3e4 100644 --- a/src/auditordb/0002-auditor_pending_deposits.sql +++ b/src/auditordb/0002-auditor_pending_deposits.sql @@ -17,9 +17,9 @@ CREATE TABLE IF NOT EXISTS auditor_pending_deposits ( row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY, - total_amount taler_amount, - wire_target_h_payto BYTEA, - batch_deposit_serial_id BIGINT, - deadline BIGINT, + total_amount taler_amount NOT NULL, + wire_target_h_payto BYTEA NOT NULL CHECK (LENGTH(wire_target_h_payto)=32), + batch_deposit_serial_id BIGINT NOT NULL, + deadline BIGINT NOT NULL, suppressed BOOLEAN NOT NULL DEFAULT FALSE ); diff --git a/src/auditordb/0002-auditor_purse_not_closed_inconsistencies.sql b/src/auditordb/0002-auditor_purse_not_closed_inconsistencies.sql index e7f6078f0..79a6ec432 100644 --- a/src/auditordb/0002-auditor_purse_not_closed_inconsistencies.sql +++ b/src/auditordb/0002-auditor_purse_not_closed_inconsistencies.sql @@ -14,13 +14,13 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- -SET search_path TO auditor; + CREATE TABLE IF NOT EXISTS auditor_purse_not_closed_inconsistencies ( - row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE , - purse_pub BYTEA PRIMARY KEY, - amount taler_amount, - expiration_date BIGINT, + row_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + purse_pub BYTEA NOT NULL CHECK (LENGTH(purse_pub)=32), + amount taler_amount NOT NULL, + expiration_date BIGINT NOT NULL, suppressed BOOLEAN NOT NULL DEFAULT FALSE ); COMMENT ON TABLE auditor_purse_not_closed_inconsistencies diff --git a/src/auditordb/0002-auditor_purses.sql b/src/auditordb/0002-auditor_purses.sql index 9cfe2b095..c9c108dc9 100644 --- a/src/auditordb/0002-auditor_purses.sql +++ b/src/auditordb/0002-auditor_purses.sql @@ -1,6 +1,6 @@ -- -- This file is part of TALER --- Copyright (C) 2014--2022 Taler Systems SA +-- Copyright (C) 2014--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 @@ -15,8 +15,8 @@ -- CREATE TABLE auditor_purses - (auditor_purses_rowid BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE - ,purse_pub BYTEA PRIMARY KEY CHECK(LENGTH(purse_pub)=32) + (auditor_purses_rowid BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE NOT NULL + ,purse_pub BYTEA PRIMARY KEY CHECK(LENGTH(purse_pub)=32) NOT NULL ,balance taler_amount NOT NULL DEFAULT(0,0) ,target taler_amount NOT NULL ,expiration_date BIGINT NOT NULL diff --git a/src/auditordb/0002-auditor_refreshes_hanging.sql b/src/auditordb/0002-auditor_refreshes_hanging.sql index c42d17c6c..ebe3368ca 100644 --- a/src/auditordb/0002-auditor_refreshes_hanging.sql +++ b/src/auditordb/0002-auditor_refreshes_hanging.sql @@ -14,12 +14,12 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- -SET search_path TO auditor; + CREATE TABLE IF NOT EXISTS auditor_refreshes_hanging ( - row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE, - amount taler_amount, - coin_pub BYTEA PRIMARY KEY, + row_id BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + problem_row_id BIGINT NOT NULL, + amount taler_amount NOT NULL, suppressed BOOLEAN NOT NULL DEFAULT FALSE ); COMMENT ON TABLE auditor_refreshes_hanging diff --git a/src/auditordb/0002-auditor_reserve_balance_insufficient_inconsistency.sql b/src/auditordb/0002-auditor_reserve_balance_insufficient_inconsistency.sql index 533f35681..83e93a4e7 100644 --- a/src/auditordb/0002-auditor_reserve_balance_insufficient_inconsistency.sql +++ b/src/auditordb/0002-auditor_reserve_balance_insufficient_inconsistency.sql @@ -14,13 +14,12 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- -SET search_path TO auditor; CREATE TABLE IF NOT EXISTS auditor_reserve_balance_insufficient_inconsistency ( row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY, reserve_pub BYTEA NOT NULL CHECK (LENGTH(reserve_pub)=32), - inconsistency_gain BOOLEAN, - inconsistency_amount taler_amount, + inconsistency_gain BOOLEAN NOT NULL, + inconsistency_amount taler_amount NOT NULL, suppressed BOOLEAN NOT NULL DEFAULT FALSE ); COMMENT ON TABLE auditor_reserve_balance_insufficient_inconsistency diff --git a/src/auditordb/0002-auditor_reserve_balance_summary_wrong_inconsistency.sql b/src/auditordb/0002-auditor_reserve_balance_summary_wrong_inconsistency.sql index 12618d101..7679f93f0 100644 --- a/src/auditordb/0002-auditor_reserve_balance_summary_wrong_inconsistency.sql +++ b/src/auditordb/0002-auditor_reserve_balance_summary_wrong_inconsistency.sql @@ -14,13 +14,13 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- -SET search_path TO auditor; + CREATE TABLE IF NOT EXISTS auditor_reserve_balance_summary_wrong_inconsistency ( row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY, - reserve_pub BYTEA, - exchange_amount taler_amount, - auditor_amount taler_amount, + reserve_pub BYTEA NOT NULL CHECK (LENGTH(reserve_pub)=32), + exchange_amount taler_amount NOT NULL, + auditor_amount taler_amount NOT NULL, suppressed BOOLEAN NOT NULL DEFAULT FALSE ); COMMENT ON TABLE auditor_reserve_balance_summary_wrong_inconsistency diff --git a/src/auditordb/0002-auditor_reserve_in_inconsistency.sql b/src/auditordb/0002-auditor_reserve_in_inconsistency.sql index e2e8aed05..cbf695406 100644 --- a/src/auditordb/0002-auditor_reserve_in_inconsistency.sql +++ b/src/auditordb/0002-auditor_reserve_in_inconsistency.sql @@ -18,12 +18,13 @@ SET search_path TO auditor; CREATE TABLE IF NOT EXISTS auditor_reserve_in_inconsistency ( row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY, - amount_exchange_expected taler_amount, - amount_wired taler_amount, - reserve_pub BYTEA, - timestamp BIGINT, - account BYTEA, - diagnostic BYTEA, + bank_row_id INT8 NOT NULL, + amount_exchange_expected taler_amount NOT NULL, + amount_wired taler_amount NOT NULL, + reserve_pub BYTEA NOT NULL CHECK (LENGTH(reserve_pub)=32), + timestamp BIGINT NOT NULL, + account TEXT NOT NULL, + diagnostic TEXT NOT NULL, suppressed BOOLEAN NOT NULL DEFAULT FALSE ); COMMENT ON TABLE auditor_reserve_in_inconsistency diff --git a/src/auditordb/0002-auditor_reserve_not_closed_inconsistency.sql b/src/auditordb/0002-auditor_reserve_not_closed_inconsistency.sql index ef0381bd1..5de538a16 100644 --- a/src/auditordb/0002-auditor_reserve_not_closed_inconsistency.sql +++ b/src/auditordb/0002-auditor_reserve_not_closed_inconsistency.sql @@ -14,14 +14,13 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- -SET search_path TO auditor; CREATE TABLE IF NOT EXISTS auditor_reserve_not_closed_inconsistency ( row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE , - reserve_pub BYTEA PRIMARY KEY, - balance taler_amount, + reserve_pub BYTEA PRIMARY KEY NOT NULL CHECK (LENGTH(reserve_pub)=32), + balance taler_amount NOT NULL, expiration_time BIGINT, - diagnostic BYTEA, + diagnostic TEXT, suppressed BOOLEAN NOT NULL DEFAULT FALSE ); COMMENT ON TABLE auditor_reserve_not_closed_inconsistency diff --git a/src/auditordb/0002-auditor_row_inconsistency.sql b/src/auditordb/0002-auditor_row_inconsistency.sql index 6fae517bf..c033814e4 100644 --- a/src/auditordb/0002-auditor_row_inconsistency.sql +++ b/src/auditordb/0002-auditor_row_inconsistency.sql @@ -14,7 +14,7 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- -SET search_path TO auditor; + CREATE TABLE IF NOT EXISTS auditor_row_inconsistency ( row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY, diff --git a/src/auditordb/0002-auditor_row_minor_inconsistencies.sql b/src/auditordb/0002-auditor_row_minor_inconsistencies.sql index d50828865..b1ccf59b8 100644 --- a/src/auditordb/0002-auditor_row_minor_inconsistencies.sql +++ b/src/auditordb/0002-auditor_row_minor_inconsistencies.sql @@ -14,13 +14,13 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- -SET search_path TO auditor; -CREATE TABLE IF NOT EXISTS auditor_row_minor_inconsistency +CREATE TABLE IF NOT EXISTS auditor_row_minor_inconsistencies ( row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY, - row_table BYTEA, - diagnostic BYTEA, + row_table TEXT NOT NULL, + problem_row BIGINT NOT NULL, + diagnostic TEXT NOT NULL, suppressed BOOLEAN NOT NULL DEFAULT FALSE ); -COMMENT ON TABLE auditor_row_minor_inconsistency - IS 'Report a (serious) row inconsistency in the exchange''s database.'; +COMMENT ON TABLE auditor_row_minor_inconsistencies + IS 'Report a (minor) row inconsistency in the exchange''s database.'; diff --git a/src/auditordb/0002-auditor_wire_format_inconsistency.sql b/src/auditordb/0002-auditor_wire_format_inconsistency.sql index dc95f7956..e6dff0562 100644 --- a/src/auditordb/0002-auditor_wire_format_inconsistency.sql +++ b/src/auditordb/0002-auditor_wire_format_inconsistency.sql @@ -14,13 +14,13 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- -SET search_path TO auditor; + CREATE TABLE IF NOT EXISTS auditor_wire_format_inconsistency ( row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY, - amount taler_amount, - wire_offset BIGINT, - diagnostic BYTEA, + amount taler_amount NOT NULL, + wire_offset BIGINT NOT NULL, + diagnostic TEXT NOT NULL, suppressed BOOLEAN NOT NULL DEFAULT FALSE ); COMMENT ON TABLE auditor_wire_format_inconsistency diff --git a/src/auditordb/0002-auditor_wire_out_inconsistency.sql b/src/auditordb/0002-auditor_wire_out_inconsistency.sql index 484fd2ac6..d46c2b283 100644 --- a/src/auditordb/0002-auditor_wire_out_inconsistency.sql +++ b/src/auditordb/0002-auditor_wire_out_inconsistency.sql @@ -14,13 +14,14 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- -SET search_path TO auditor; CREATE TABLE IF NOT EXISTS auditor_wire_out_inconsistency ( row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY, destination_account TEXT NOT NULL, - expected taler_amount, - claimed taler_amount, + diagnostic TEXT NOT NULL, + wire_out_serial_id INT8 NOT NULL, + expected taler_amount NOT NULL, + claimed taler_amount NOT NULL, suppressed BOOLEAN NOT NULL DEFAULT FALSE ); COMMENT ON TABLE auditor_wire_out_inconsistency diff --git a/src/auditordb/Makefile.am b/src/auditordb/Makefile.am index 36c6917a8..7f6cf8537 100644 --- a/src/auditordb/Makefile.am +++ b/src/auditordb/Makefile.am @@ -59,8 +59,9 @@ endif # MARK: CRUD libtaler_plugin_auditordb_postgres_la_SOURCES = \ - plugin_auditordb_postgres.c pg_helper.h \ - pg_delete_deposit_confirmations.c pg_delete_deposit_confirmations.h \ + plugin_auditordb_postgres.c \ + pg_helper.h pg_helper.c \ + pg_delete_generic.c pg_delete_generic.h \ pg_delete_pending_deposit.c pg_delete_pending_deposit.h \ pg_delete_purse_info.c pg_delete_purse_info.h \ pg_del_denomination_balance.h pg_del_denomination_balance.c \ @@ -76,6 +77,7 @@ libtaler_plugin_auditordb_postgres_la_SOURCES = \ pg_insert_balance.c pg_insert_balance.h \ pg_insert_denomination_balance.c pg_insert_denomination_balance.h \ pg_insert_deposit_confirmation.c pg_insert_deposit_confirmation.h \ + pg_get_progress_points.h pg_get_progress_points.c \ pg_insert_historic_reserve_revenue.c pg_insert_historic_reserve_revenue.h \ pg_insert_pending_deposit.c pg_insert_pending_deposit.h \ pg_insert_purse_info.c pg_insert_purse_info.h \ @@ -96,95 +98,50 @@ libtaler_plugin_auditordb_postgres_la_SOURCES = \ pg_insert_amount_arithmetic_inconsistency.c pg_insert_amount_arithmetic_inconsistency.h \ pg_insert_coin_inconsistency.c pg_insert_coin_inconsistency.h \ pg_insert_row_inconsistency.c pg_insert_row_inconsistency.h \ - pg_del_amount_arithmetic_inconsistency.c pg_del_amount_arithmetic_inconsistency.h \ - pg_del_coin_inconsistency.c pg_del_coin_inconsistency.h \ - pg_del_row_inconsistency.c pg_del_row_inconsistency.h \ - pg_del_emergency.c pg_del_emergency.h \ pg_insert_emergency.c pg_insert_emergency.h \ pg_get_emergency.c pg_get_emergency.h \ - pg_del_emergency_by_count.c pg_del_emergency_by_count.h \ pg_insert_emergency_by_count.c pg_insert_emergency_by_count.h \ pg_get_emergency_by_count.c pg_get_emergency_by_count.h \ - pg_del_denomination_key_validity_withdraw_inconsistency.c pg_del_denomination_key_validity_withdraw_inconsistency.h \ pg_insert_denomination_key_validity_withdraw_inconsistency.c pg_insert_denomination_key_validity_withdraw_inconsistency.h \ pg_get_denomination_key_validity_withdraw_inconsistency.c pg_get_denomination_key_validity_withdraw_inconsistency.h \ - pg_del_purse_not_closed_inconsistencies.c pg_del_purse_not_closed_inconsistencies.h \ pg_insert_purse_not_closed_inconsistencies.c pg_insert_purse_not_closed_inconsistencies.h \ pg_get_purse_not_closed_inconsistencies.c pg_get_purse_not_closed_inconsistencies.h \ - pg_del_reserve_balance_insufficient_inconsistency.c pg_del_reserve_balance_insufficient_inconsistency.h \ -pg_insert_reserve_balance_insufficient_inconsistency.c pg_insert_reserve_balance_insufficient_inconsistency.h \ -pg_get_reserve_balance_insufficient_inconsistency.c pg_get_reserve_balance_insufficient_inconsistency.h \ -pg_del_bad_sig_losses.c pg_del_bad_sig_losses.h \ -pg_insert_bad_sig_losses.c pg_insert_bad_sig_losses.h \ -pg_get_bad_sig_losses.c pg_get_bad_sig_losses.h \ -pg_update_bad_sig_losses.c pg_update_bad_sig_losses.h \ -pg_del_auditor_closure_lags.c pg_del_auditor_closure_lags.h \ -pg_insert_auditor_closure_lags.c pg_insert_auditor_closure_lags.h \ -pg_get_auditor_closure_lags.c pg_get_auditor_closure_lags.h \ -pg_del_refreshes_hanging.c pg_del_refreshes_hanging.h \ -pg_insert_refreshes_hanging.c pg_insert_refreshes_hanging.h \ -pg_get_refreshes_hanging.c pg_get_refreshes_hanging.h \ -pg_update_emergency_by_count.c pg_update_emergency_by_count.h \ -pg_update_row_inconsistency.c pg_update_row_inconsistency.h \ -pg_update_purse_not_closed_inconsistencies.c pg_update_purse_not_closed_inconsistencies.h \ -pg_update_reserve_balance_insufficient_inconsistency.c pg_update_reserve_balance_insufficient_inconsistency.h \ -pg_update_coin_inconsistency.c pg_update_coin_inconsistency.h \ -pg_update_denomination_key_validity_withdraw_inconsistency.c pg_update_denomination_key_validity_withdraw_inconsistency.h \ -pg_update_refreshes_hanging.c pg_update_refreshes_hanging.h \ -pg_update_emergency.c pg_update_emergency.h \ -pg_update_closure_lags.c pg_update_closure_lags.h \ -pg_get_reserve_in_inconsistency.c pg_get_reserve_in_inconsistency.h \ -pg_del_reserve_in_inconsistency.c pg_del_reserve_in_inconsistency.h \ -pg_insert_reserve_in_inconsistency.c pg_insert_reserve_in_inconsistency.h \ -pg_update_reserve_in_inconsistency.c pg_update_reserve_in_inconsistency.h \ -pg_get_reserve_not_closed_inconsistency.c pg_get_reserve_not_closed_inconsistency.h \ -pg_del_reserve_not_closed_inconsistency.c pg_del_reserve_not_closed_inconsistency.h \ -pg_insert_reserve_not_closed_inconsistency.c pg_insert_reserve_not_closed_inconsistency.h \ -pg_update_reserve_not_closed_inconsistency.c pg_update_reserve_not_closed_inconsistency.h \ -pg_get_denominations_without_sigs.c pg_get_denominations_without_sigs.h \ -pg_del_denominations_without_sigs.c pg_del_denominations_without_sigs.h \ -pg_insert_denominations_without_sigs.c pg_insert_denominations_without_sigs.h \ -pg_update_denominations_without_sigs.c pg_update_denominations_without_sigs.h \ -pg_get_misattribution_in_inconsistency.c pg_get_misattribution_in_inconsistency.h \ -pg_del_misattribution_in_inconsistency.c pg_del_misattribution_in_inconsistency.h \ -pg_insert_misattribution_in_inconsistency.c pg_insert_misattribution_in_inconsistency.h \ -pg_update_misattribution_in_inconsistency.c pg_update_misattribution_in_inconsistency.h \ -pg_update_balance.c pg_update_balance.h \ -pg_get_reserves.c pg_get_reserves.h \ -pg_del_reserves.c pg_del_reserves.h \ -pg_get_purses.c pg_get_purses.h \ -pg_del_purses.c pg_del_purses.h \ -pg_insert_historic_denom_revenue.c pg_insert_historic_denom_revenue.h \ -pg_get_denomination_pending.c pg_get_denomination_pending.h \ -pg_del_denomination_pending.c pg_del_denomination_pending.h \ -pg_insert_denomination_pending.c pg_insert_denomination_pending.h \ -pg_update_denomination_pending.c pg_update_denomination_pending.h \ -pg_get_exchange_signkeys.c pg_get_exchange_signkeys.h \ -pg_get_wire_format_inconsistency.c pg_get_wire_format_inconsistency.h \ -pg_del_wire_format_inconsistency.c pg_del_wire_format_inconsistency.h \ -pg_insert_wire_format_inconsistency.c pg_insert_wire_format_inconsistency.h \ -pg_update_wire_format_inconsistency.c pg_update_wire_format_inconsistency.h \ -pg_get_wire_out_inconsistency.c pg_get_wire_out_inconsistency.h \ -pg_del_wire_out_inconsistency.c pg_del_wire_out_inconsistency.h \ -pg_insert_wire_out_inconsistency.c pg_insert_wire_out_inconsistency.h \ -pg_update_wire_out_inconsistency.c pg_update_wire_out_inconsistency.h \ -pg_get_reserve_balance_summary_wrong_inconsistency.c pg_get_reserve_balance_summary_wrong_inconsistency.h \ -pg_del_reserve_balance_summary_wrong_inconsistency.c pg_del_reserve_balance_summary_wrong_inconsistency.h \ -pg_insert_reserve_balance_summary_wrong_inconsistency.c pg_insert_reserve_balance_summary_wrong_inconsistency.h \ -pg_update_reserve_balance_summary_wrong_inconsistency.c pg_update_reserve_balance_summary_wrong_inconsistency.h \ -pg_get_row_minor_inconsistencies.c pg_get_row_minor_inconsistencies.h \ -pg_del_row_minor_inconsistencies.c pg_del_row_minor_inconsistencies.h \ -pg_insert_row_minor_inconsistencies.c pg_insert_row_minor_inconsistencies.h \ -pg_update_row_minor_inconsistencies.c pg_update_row_minor_inconsistencies.h \ -pg_del_auditor_progress.c pg_del_auditor_progress.h \ -pg_get_fee_time_inconsistency.c pg_get_fee_time_inconsistency.h \ -pg_del_fee_time_inconsistency.c pg_del_fee_time_inconsistency.h \ -pg_insert_fee_time_inconsistency.c pg_insert_fee_time_inconsistency.h \ -pg_update_fee_time_inconsistency.c pg_update_fee_time_inconsistency.h \ -pg_get_balances.c pg_get_balances.h \ -pg_insert_exchange_signkey.c pg_insert_exchange_signkey.h \ -pg_update_deposit_confirmations.c pg_update_deposit_confirmations.h \ -pg_update_amount_arithmetic_inconsistency.c pg_update_amount_arithmetic_inconsistency.h + pg_insert_reserve_balance_insufficient_inconsistency.c pg_insert_reserve_balance_insufficient_inconsistency.h \ + pg_get_reserve_balance_insufficient_inconsistency.c pg_get_reserve_balance_insufficient_inconsistency.h \ + pg_insert_bad_sig_losses.c pg_insert_bad_sig_losses.h \ + pg_get_bad_sig_losses.c pg_get_bad_sig_losses.h \ + pg_insert_auditor_closure_lags.c pg_insert_auditor_closure_lags.h \ + pg_get_auditor_closure_lags.c pg_get_auditor_closure_lags.h \ + pg_insert_refreshes_hanging.c pg_insert_refreshes_hanging.h \ + pg_get_refreshes_hanging.c pg_get_refreshes_hanging.h \ + pg_get_reserve_in_inconsistency.c pg_get_reserve_in_inconsistency.h \ + pg_insert_reserve_in_inconsistency.c pg_insert_reserve_in_inconsistency.h \ + pg_get_reserve_not_closed_inconsistency.c pg_get_reserve_not_closed_inconsistency.h \ + pg_insert_reserve_not_closed_inconsistency.c pg_insert_reserve_not_closed_inconsistency.h \ + pg_get_denominations_without_sigs.c pg_get_denominations_without_sigs.h \ + pg_insert_denominations_without_sigs.c pg_insert_denominations_without_sigs.h \ + pg_get_misattribution_in_inconsistency.c pg_get_misattribution_in_inconsistency.h \ + pg_insert_misattribution_in_inconsistency.c pg_insert_misattribution_in_inconsistency.h \ + pg_update_balance.c pg_update_balance.h \ + pg_get_reserves.c pg_get_reserves.h \ + pg_get_purses.c pg_get_purses.h \ + pg_insert_historic_denom_revenue.c pg_insert_historic_denom_revenue.h \ + pg_get_denomination_pending.c pg_get_denomination_pending.h \ + pg_insert_denomination_pending.c pg_insert_denomination_pending.h \ + pg_get_exchange_signkeys.c pg_get_exchange_signkeys.h \ + pg_get_wire_format_inconsistency.c pg_get_wire_format_inconsistency.h \ + pg_insert_wire_format_inconsistency.c pg_insert_wire_format_inconsistency.h \ + pg_get_wire_out_inconsistency.c pg_get_wire_out_inconsistency.h \ + pg_insert_wire_out_inconsistency.c pg_insert_wire_out_inconsistency.h \ + pg_delete_wire_out_inconsistency_if_matching.c pg_delete_wire_out_inconsistency_if_matching.h \ + pg_get_reserve_balance_summary_wrong_inconsistency.c pg_get_reserve_balance_summary_wrong_inconsistency.h \ + pg_insert_reserve_balance_summary_wrong_inconsistency.c pg_insert_reserve_balance_summary_wrong_inconsistency.h \ + pg_get_row_minor_inconsistencies.c pg_get_row_minor_inconsistencies.h \ + pg_insert_row_minor_inconsistencies.c pg_insert_row_minor_inconsistencies.h \ + pg_get_fee_time_inconsistency.c pg_get_fee_time_inconsistency.h \ + pg_insert_fee_time_inconsistency.c pg_insert_fee_time_inconsistency.h \ + pg_get_balances.c pg_get_balances.h \ + pg_insert_exchange_signkey.c pg_insert_exchange_signkey.h libtaler_plugin_auditordb_postgres_la_LDFLAGS = \ $(TALER_PLUGIN_LDFLAGS) diff --git a/src/auditordb/auditor_do_get_auditor_progress.sql b/src/auditordb/auditor_do_get_auditor_progress.sql index 9371cf67b..afe6112c2 100644 --- a/src/auditordb/auditor_do_get_auditor_progress.sql +++ b/src/auditordb/auditor_do_get_auditor_progress.sql @@ -15,22 +15,28 @@ -- -- @author Christian Grothoff -CREATE OR REPLACE FUNCTION auditor_do_get_auditor_progress( +DROP FUNCTION IF EXISTS auditor_do_get_auditor_progress; +CREATE FUNCTION auditor_do_get_auditor_progress( IN in_keys TEXT[]) -RETURNS INT8 +RETURNS SETOF INT8 LANGUAGE plpgsql AS $$ DECLARE - my_key TEXT; + ini_key TEXT; my_off INT8; BEGIN - FOREACH my_key IN ARRAY in_keys + FOREACH ini_key IN ARRAY in_keys LOOP SELECT progress_offset INTO my_off FROM auditor_progress - WHERE progress_key=my_key; - RETURN my_off; + WHERE progress_key=ini_key; + IF FOUND + THEN + RETURN NEXT my_off; + ELSE + RETURN NEXT NULL; + END IF; END LOOP; END $$; diff --git a/src/auditordb/auditor_do_get_balance.sql b/src/auditordb/auditor_do_get_balance.sql index 782a31f89..ad9ed0108 100644 --- a/src/auditordb/auditor_do_get_balance.sql +++ b/src/auditordb/auditor_do_get_balance.sql @@ -15,9 +15,10 @@ -- -- @author Christian Grothoff +DROP FUNCTION IF EXISTS auditor_do_get_balance; CREATE OR REPLACE FUNCTION auditor_do_get_balance( IN in_keys TEXT[]) -RETURNS taler_amount +RETURNS SETOF taler_amount LANGUAGE plpgsql AS $$ DECLARE @@ -36,9 +37,9 @@ BEGIN THEN my_val.val = my_rec.val; my_val.frac = my_rec.frac; - RETURN my_val; + RETURN NEXT my_val; ELSE - RETURN NULL; + RETURN NEXT NULL; END IF; END LOOP; END $$; diff --git a/src/auditordb/pg_del_amount_arithmetic_inconsistency.c b/src/auditordb/pg_del_amount_arithmetic_inconsistency.c deleted file mode 100644 index 5af3bdda7..000000000 --- a/src/auditordb/pg_del_amount_arithmetic_inconsistency.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - 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 "pg_del_amount_arithmetic_inconsistency.h" - -#include "taler_pq_lib.h" -#include "pg_helper.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_del_amount_arithmetic_inconsistency ( - void *cls, - uint64_t row_id) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&row_id), - GNUNET_PQ_query_param_end - }; - - PREPARE (pg, - "auditor_delete_amount_arithmetic_inconsistency", - "DELETE" - " FROM auditor_amount_arithmetic_inconsistency" - " WHERE row_id=$1;"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "auditor_delete_amount_arithmetic_inconsistency", - params); -} diff --git a/src/auditordb/pg_del_amount_arithmetic_inconsistency.h b/src/auditordb/pg_del_amount_arithmetic_inconsistency.h deleted file mode 100644 index ff7f12cf2..000000000 --- a/src/auditordb/pg_del_amount_arithmetic_inconsistency.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - 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 SRC_PG_DEL_AMOUNT_ARITHMETIC_INCONSISTENCY_H -#define SRC_PG_DEL_AMOUNT_ARITHMETIC_INCONSISTENCY_H - -#include "taler_util.h" -#include "taler_json_lib.h" -#include "taler_auditordb_plugin.h" - -/** - * Delete a row from the deposit confirmations table. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param row_id row to delete - * @return query transaction status - */ -enum GNUNET_DB_QueryStatus -TAH_PG_del_amount_arithmetic_inconsistency ( - void *cls, - uint64_t row_id); - -#endif // SRC_PG_DEL_AMOUNT_ARITHMETIC_INCONSISTENCY_H diff --git a/src/auditordb/pg_del_auditor_closure_lags.c b/src/auditordb/pg_del_auditor_closure_lags.c deleted file mode 100644 index 89f230af3..000000000 --- a/src/auditordb/pg_del_auditor_closure_lags.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - 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 "pg_del_auditor_closure_lags.h" - -#include "taler_pq_lib.h" -#include "pg_helper.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_del_auditor_closure_lags ( - void *cls, - uint64_t row_id) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&row_id), - GNUNET_PQ_query_param_end - }; - - PREPARE (pg, - "auditor_delete_auditor_closure_lags", - "DELETE" - " FROM auditor_closure_lags" - " WHERE row_id=$1;"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "auditor_delete_auditor_closure_lags", - params); -}
\ No newline at end of file diff --git a/src/auditordb/pg_del_auditor_closure_lags.h b/src/auditordb/pg_del_auditor_closure_lags.h deleted file mode 100644 index 7c6f2db51..000000000 --- a/src/auditordb/pg_del_auditor_closure_lags.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - 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 SRC_PG_DEL_AUDITOR_CLOSURE_LAGS_H -#define SRC_PG_DEL_AUDITOR_CLOSURE_LAGS_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -/** - * Delete a row from the auditor closure lags table. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param row_id row to delete - * @return query transaction status - */ -enum GNUNET_DB_QueryStatus -TAH_PG_del_auditor_closure_lags ( - void *cls, - uint64_t row_id); - -#endif // SRC_PG_DEL_AUDITOR_CLOSURE_LAGS_H diff --git a/src/auditordb/pg_del_auditor_progress.c b/src/auditordb/pg_del_auditor_progress.c deleted file mode 100644 index 087e2783c..000000000 --- a/src/auditordb/pg_del_auditor_progress.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - 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 "pg_del_auditor_progress.h" - - -#include "taler_pq_lib.h" -#include "pg_helper.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_del_progress ( - void *cls, - uint64_t row_id) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&row_id), - GNUNET_PQ_query_param_end - }; - - PREPARE (pg, - "auditor_delete_auditor_closure_lags", - "DELETE" - " FROM auditor_progress" - " WHERE row_id=$1;"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "auditor_delete_auditor_closure_lags", - params); -}
\ No newline at end of file diff --git a/src/auditordb/pg_del_auditor_progress.h b/src/auditordb/pg_del_auditor_progress.h deleted file mode 100644 index 51e974040..000000000 --- a/src/auditordb/pg_del_auditor_progress.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - 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 SRC_PG_DEL_AUDITOR_PROGRESS_H -#define SRC_PG_DEL_AUDITOR_PROGRESS_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -/** - * Delete a row from the progress table. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param row_id row to delete - * @return query transaction status - */ -enum GNUNET_DB_QueryStatus -TAH_PG_del_progress ( - void *cls, - uint64_t row_id); - -#endif // SRC_PG_DEL_AUDITOR_PROGRESS_H diff --git a/src/auditordb/pg_del_bad_sig_losses.c b/src/auditordb/pg_del_bad_sig_losses.c deleted file mode 100644 index 2bf48642c..000000000 --- a/src/auditordb/pg_del_bad_sig_losses.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - 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 "pg_del_bad_sig_losses.h" - -#include "taler_pq_lib.h" -#include "pg_helper.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_del_bad_sig_losses ( - void *cls, - uint64_t row_id) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&row_id), - GNUNET_PQ_query_param_end - }; - - PREPARE (pg, - "auditor_delete_bad_sig_losses", - "DELETE" - " FROM auditor_bad_sig_losses" - " WHERE row_id=$1;"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "auditor_delete_bad_sig_losses", - params); -}
\ No newline at end of file diff --git a/src/auditordb/pg_del_bad_sig_losses.h b/src/auditordb/pg_del_bad_sig_losses.h deleted file mode 100644 index 4881e8715..000000000 --- a/src/auditordb/pg_del_bad_sig_losses.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - 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 SRC_PG_DEL_BAD_SIG_LOSSES_H -#define SRC_PG_DEL_BAD_SIG_LOSSES_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -/** - * Delete a row from the bad sig losses table. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param row_id row to delete - * @return query transaction status - */ -enum GNUNET_DB_QueryStatus -TAH_PG_del_bad_sig_losses ( - void *cls, - uint64_t row_id); - -#endif // SRC_PG_DEL_BAD_SIG_LOSSES_H diff --git a/src/auditordb/pg_del_coin_inconsistency.c b/src/auditordb/pg_del_coin_inconsistency.c deleted file mode 100644 index d1426c955..000000000 --- a/src/auditordb/pg_del_coin_inconsistency.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - 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 "pg_del_coin_inconsistency.h" - -#include "taler_pq_lib.h" -#include "pg_helper.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_del_coin_inconsistency ( - void *cls, - uint64_t row_id) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&row_id), - GNUNET_PQ_query_param_end - }; - - PREPARE (pg, - "auditor_delete_coin_inconsistency", - "DELETE" - " FROM auditor_coin_inconsistency" - " WHERE row_id=$1;"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "auditor_delete_coin_inconsistency", - params); -} diff --git a/src/auditordb/pg_del_coin_inconsistency.h b/src/auditordb/pg_del_coin_inconsistency.h deleted file mode 100644 index 8fc43c1c5..000000000 --- a/src/auditordb/pg_del_coin_inconsistency.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - 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 SRC_PG_DEL_COIN_INCONSISTENCY_H -#define SRC_PG_DEL_COIN_INCONSISTENCY_H - -#include "taler_util.h" -#include "taler_json_lib.h" -#include "taler_auditordb_plugin.h" - -/** - * Delete a row from the coin inconsistency table. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param row_id row to delete - * @return query transaction status - */ -enum GNUNET_DB_QueryStatus -TAH_PG_del_coin_inconsistency ( - void *cls, - uint64_t row_id); - -#endif // SRC_PG_DEL_COIN_INCONSISTENCY_H diff --git a/src/auditordb/pg_del_denomination_key_validity_withdraw_inconsistency.c b/src/auditordb/pg_del_denomination_key_validity_withdraw_inconsistency.c deleted file mode 100644 index fa8d01580..000000000 --- a/src/auditordb/pg_del_denomination_key_validity_withdraw_inconsistency.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - 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 "pg_del_denomination_key_validity_withdraw_inconsistency.h" - -#include "taler_pq_lib.h" -#include "pg_helper.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_del_denomination_key_validity_withdraw_inconsistency ( - void *cls, - uint64_t row_id) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&row_id), - GNUNET_PQ_query_param_end - }; - - PREPARE (pg, - "auditor_delete_denomination_key_validity_withdraw_inconsistency", - "DELETE" - " FROM auditor_denomination_key_validity_withdraw_inconsistency" - " WHERE row_id=$1;"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "auditor_delete_denomination_key_validity_withdraw_inconsistency", - params); -}
\ No newline at end of file diff --git a/src/auditordb/pg_del_denomination_key_validity_withdraw_inconsistency.h b/src/auditordb/pg_del_denomination_key_validity_withdraw_inconsistency.h deleted file mode 100644 index 9c11dd768..000000000 --- a/src/auditordb/pg_del_denomination_key_validity_withdraw_inconsistency.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - 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 SRC_PG_DEL_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_H -#define SRC_PG_DEL_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -/** - * Delete a row from the denom key validity withdraw inconsistency table. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param row_id row to delete - * @return query transaction status - */ -enum GNUNET_DB_QueryStatus -TAH_PG_del_denomination_key_validity_withdraw_inconsistency ( - void *cls, - uint64_t row_id); - -#endif // SRC_PG_DEL_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_H diff --git a/src/auditordb/pg_del_denomination_pending.c b/src/auditordb/pg_del_denomination_pending.c deleted file mode 100644 index ac5ab7211..000000000 --- a/src/auditordb/pg_del_denomination_pending.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - 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 "pg_del_denomination_pending.h" - -#include "taler_pq_lib.h" -#include "pg_helper.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_del_denomination_pending ( - void *cls, - uint64_t row_id) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&row_id), - GNUNET_PQ_query_param_end - }; - - PREPARE (pg, - "auditor_delete_denomination_pending", - "DELETE" - " FROM auditor_denomination_pending" - " WHERE row_id=$1;"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "auditor_delete_denomination_pending", - params); -} diff --git a/src/auditordb/pg_del_denomination_pending.h b/src/auditordb/pg_del_denomination_pending.h deleted file mode 100644 index 91e7fea59..000000000 --- a/src/auditordb/pg_del_denomination_pending.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - 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 SRC_PG_DEL_DENOMINATION_PENDING_H -#define SRC_PG_DEL_DENOMINATION_PENDING_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -/** - * Delete a row from the bad sig losses table. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param row_id row to delete - * @return query transaction status - */ -enum GNUNET_DB_QueryStatus -TAH_PG_del_denomination_pending ( - void *cls, - uint64_t row_id); - -#endif // SRC_PG_DEL_DENOMINATION_PENDING_H diff --git a/src/auditordb/pg_del_denominations_without_sigs.c b/src/auditordb/pg_del_denominations_without_sigs.c deleted file mode 100644 index 03c222105..000000000 --- a/src/auditordb/pg_del_denominations_without_sigs.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - 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 "pg_del_denominations_without_sigs.h" - -#include "taler_pq_lib.h" -#include "pg_helper.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_del_denominations_without_sigs ( - void *cls, - uint64_t row_id) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&row_id), - GNUNET_PQ_query_param_end - }; - - PREPARE (pg, - "auditor_delete_denominations_without_sigs", - "DELETE" - " FROM auditor_denominations_without_sigs" - " WHERE row_id=$1;"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "auditor_delete_denominations_without_sigs", - params); -} diff --git a/src/auditordb/pg_del_denominations_without_sigs.h b/src/auditordb/pg_del_denominations_without_sigs.h deleted file mode 100644 index ae090b5c8..000000000 --- a/src/auditordb/pg_del_denominations_without_sigs.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - 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 SRC_PG_DEL_DENOMINATIONS_WITHOUT_SIGS_H -#define SRC_PG_DEL_DENOMINATIONS_WITHOUT_SIGS_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -/** - * Delete a row from the bad sig losses table. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param row_id row to delete - * @return query transaction status - */ -enum GNUNET_DB_QueryStatus -TAH_PG_del_denominations_without_sigs ( - void *cls, - uint64_t row_id); - -#endif // SRC_PG_DEL_DENOMINATIONS_WITHOUT_SIGS_H diff --git a/src/auditordb/pg_del_emergency.c b/src/auditordb/pg_del_emergency.c deleted file mode 100644 index 8160dc582..000000000 --- a/src/auditordb/pg_del_emergency.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2022 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have 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 "pg_del_emergency.h" - -#include "taler_pq_lib.h" -#include "pg_helper.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_del_emergency ( - void *cls, - uint64_t row_id) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&row_id), - GNUNET_PQ_query_param_end - }; - - PREPARE (pg, - "auditor_delete_emergency", - "DELETE" - " FROM auditor_emergency" - " WHERE row_id=$1;"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "auditor_delete_emergency", - params); -}
\ No newline at end of file diff --git a/src/auditordb/pg_del_emergency_by_count.c b/src/auditordb/pg_del_emergency_by_count.c deleted file mode 100644 index 84ab0def0..000000000 --- a/src/auditordb/pg_del_emergency_by_count.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - 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 "pg_del_emergency_by_count.h" - -#include "taler_pq_lib.h" -#include "pg_helper.h" - - -enum GNUNET_DB_QueryStatus -TAH_PG_del_emergency_by_count ( - void *cls, - uint64_t row_id) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&row_id), - GNUNET_PQ_query_param_end - }; - - PREPARE (pg, - "auditor_delete_emergency_by_count", - "DELETE" - " FROM auditor_emergency_by_count" - " WHERE row_id=$1;"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "auditor_delete_emergency_by_count", - params); -}
\ No newline at end of file diff --git a/src/auditordb/pg_del_fee_time_inconsistency.c b/src/auditordb/pg_del_fee_time_inconsistency.c deleted file mode 100644 index 94fbff42f..000000000 --- a/src/auditordb/pg_del_fee_time_inconsistency.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - 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 "pg_del_fee_time_inconsistency.h" - -#include "taler_pq_lib.h" -#include "pg_helper.h" - - -enum GNUNET_DB_QueryStatus -TAH_PG_del_fee_time_inconsistency ( - void *cls, - uint64_t row_id) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&row_id), - GNUNET_PQ_query_param_end - }; - - PREPARE (pg, - "auditor_delete_fee_time_inconsistency", - "DELETE" - " FROM auditor_fee_time_inconsistency" - " WHERE row_id=$1;"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "auditor_delete_fee_time_inconsistency", - params); -}
\ No newline at end of file diff --git a/src/auditordb/pg_del_fee_time_inconsistency.h b/src/auditordb/pg_del_fee_time_inconsistency.h deleted file mode 100644 index 49b7e253e..000000000 --- a/src/auditordb/pg_del_fee_time_inconsistency.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - 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 SRC_PG_DEL_FEE_TIME_INCONSISTENCY_H -#define SRC_PG_DEL_FEE_TIME_INCONSISTENCY_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -/** - * Delete a row from the dee time inconsistency table. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param row_id row to delete - * @return query transaction status - */ -enum GNUNET_DB_QueryStatus -TAH_PG_del_fee_time_inconsistency ( - void *cls, - uint64_t row_id); - -#endif // SRC_PG_DEL_FEE_TIME_INCONSISTENCY_H diff --git a/src/auditordb/pg_del_misattribution_in_inconsistency.c b/src/auditordb/pg_del_misattribution_in_inconsistency.c deleted file mode 100644 index c3ebd0fc6..000000000 --- a/src/auditordb/pg_del_misattribution_in_inconsistency.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - 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 "pg_del_misattribution_in_inconsistency.h" - -#include "taler_pq_lib.h" -#include "pg_helper.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_del_misattribution_in_inconsistency ( - void *cls, - uint64_t row_id) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&row_id), - GNUNET_PQ_query_param_end - }; - - PREPARE (pg, - "auditor_delete_misattribution_in_inconsistency", - "DELETE" - " FROM auditor_misattribution_in_inconsistency" - " WHERE row_id=$1;"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "auditor_delete_misattribution_in_inconsistency", - params); -} diff --git a/src/auditordb/pg_del_misattribution_in_inconsistency.h b/src/auditordb/pg_del_misattribution_in_inconsistency.h deleted file mode 100644 index 916c53dd8..000000000 --- a/src/auditordb/pg_del_misattribution_in_inconsistency.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - 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 SRC_PG_DEL_MISATTRIBUTION_IN_INCONSISTENCY_H -#define SRC_PG_DEL_MISATTRIBUTION_IN_INCONSISTENCY_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -/** - * Delete a row from the bad sig losses table. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param row_id row to delete - * @return query transaction status - */ -enum GNUNET_DB_QueryStatus -TAH_PG_del_misattribution_in_inconsistency ( - void *cls, - uint64_t row_id); - -#endif // SRC_PG_DEL_MISATTRIBUTION_IN_INCONSISTENCY_H diff --git a/src/auditordb/pg_del_purse_not_closed_inconsistencies.c b/src/auditordb/pg_del_purse_not_closed_inconsistencies.c deleted file mode 100644 index 3bc82f1e9..000000000 --- a/src/auditordb/pg_del_purse_not_closed_inconsistencies.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - 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 "pg_del_purse_not_closed_inconsistencies.h" - -#include "taler_pq_lib.h" -#include "pg_helper.h" - - -enum GNUNET_DB_QueryStatus -TAH_PG_del_purse_not_closed_inconsistencies ( - void *cls, - uint64_t row_id) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&row_id), - GNUNET_PQ_query_param_end - }; - - PREPARE (pg, - "auditor_delete_purse_not_closed_inconsistencies", - "DELETE" - " FROM auditor_purse_not_closed_inconsistencies" - " WHERE row_id=$1;"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "auditor_delete_purse_not_closed_inconsistencies", - params); -}
\ No newline at end of file diff --git a/src/auditordb/pg_del_purse_not_closed_inconsistencies.h b/src/auditordb/pg_del_purse_not_closed_inconsistencies.h deleted file mode 100644 index 25d4305e2..000000000 --- a/src/auditordb/pg_del_purse_not_closed_inconsistencies.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - 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 SRC_PG_DEL_PURSE_NOT_CLOSED_INCONSISTENCIES_H -#define SRC_PG_DEL_PURSE_NOT_CLOSED_INCONSISTENCIES_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -/** - * Delete a row from the purse not closed inconsistency table. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param row_id row to delete - * @return query transaction status - */ -enum GNUNET_DB_QueryStatus -TAH_PG_del_purse_not_closed_inconsistencies ( - void *cls, - uint64_t row_id); - -#endif // SRC_PG_DEL_PURSE_NOT_CLOSED_INCONSISTENCIES_H diff --git a/src/auditordb/pg_del_purses.c b/src/auditordb/pg_del_purses.c deleted file mode 100644 index aeeaac88a..000000000 --- a/src/auditordb/pg_del_purses.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - 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 "pg_del_purses.h" - -#include "taler_pq_lib.h" -#include "pg_helper.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_del_purses ( - void *cls, - uint64_t row_id) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&row_id), - GNUNET_PQ_query_param_end - }; - - PREPARE (pg, - "auditor_delete_purses", - "DELETE" - " FROM auditor_purses" - " WHERE row_id=$1;"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "auditor_delete_purses", - params); -} diff --git a/src/auditordb/pg_del_purses.h b/src/auditordb/pg_del_purses.h deleted file mode 100644 index e4f4566ad..000000000 --- a/src/auditordb/pg_del_purses.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - 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 SRC_PG_DEL_PURSES_H -#define SRC_PG_DEL_PURSES_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -/** - * Delete a row from the bad sig losses table. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param row_id row to delete - * @return query transaction status - */ -enum GNUNET_DB_QueryStatus -TAH_PG_del_purses ( - void *cls, - uint64_t row_id); - -#endif // SRC_PG_DEL_PURSES_H diff --git a/src/auditordb/pg_del_refreshes_hanging.c b/src/auditordb/pg_del_refreshes_hanging.c deleted file mode 100644 index 43a1cbba1..000000000 --- a/src/auditordb/pg_del_refreshes_hanging.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - 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 "pg_del_refreshes_hanging.h" - -#include "taler_pq_lib.h" -#include "pg_helper.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_del_refreshes_hanging ( - void *cls, - uint64_t row_id) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&row_id), - GNUNET_PQ_query_param_end - }; - - PREPARE (pg, - "auditor_delete_refreshes_hanging", - "DELETE" - " FROM auditor_refreshes_hanging" - " WHERE row_id=$1;"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "auditor_delete_refreshes_hanging", - params); -}
\ No newline at end of file diff --git a/src/auditordb/pg_del_refreshes_hanging.h b/src/auditordb/pg_del_refreshes_hanging.h deleted file mode 100644 index f2cdee95e..000000000 --- a/src/auditordb/pg_del_refreshes_hanging.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - 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 SRC_PG_DEL_REFRESHES_HANGING_H -#define SRC_PG_DEL_REFRESHES_HANGING_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -/** - * Delete a row from the refreshes hanging table. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param row_id row to delete - * @return query transaction status - */ -enum GNUNET_DB_QueryStatus -TAH_PG_del_refreshes_hanging ( - void *cls, - uint64_t row_id); - -#endif // SRC_PG_DEL_REFRESHES_HANGING_H diff --git a/src/auditordb/pg_del_reserve_balance_insufficient_inconsistency.c b/src/auditordb/pg_del_reserve_balance_insufficient_inconsistency.c deleted file mode 100644 index 001969e51..000000000 --- a/src/auditordb/pg_del_reserve_balance_insufficient_inconsistency.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - 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 "pg_del_reserve_balance_insufficient_inconsistency.h" - - -#include "taler_pq_lib.h" -#include "pg_helper.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_del_reserve_balance_insufficient_inconsistency ( - void *cls, - uint64_t row_id) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&row_id), - GNUNET_PQ_query_param_end - }; - - PREPARE (pg, - "auditor_delete_reserve_balance_insufficient_inconsistency", - "DELETE" - " FROM auditor_reserve_balance_insufficient_inconsistency" - " WHERE row_id=$1;"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "auditor_delete_reserve_balance_insufficient_inconsistency", - params); -}
\ No newline at end of file diff --git a/src/auditordb/pg_del_reserve_balance_insufficient_inconsistency.h b/src/auditordb/pg_del_reserve_balance_insufficient_inconsistency.h deleted file mode 100644 index 783dea493..000000000 --- a/src/auditordb/pg_del_reserve_balance_insufficient_inconsistency.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - 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 SRC_PG_DEL_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_H -#define SRC_PG_DEL_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -/** - * Delete a row from the reserve balance insufficient inconsistency table. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param row_id row to delete - * @return query transaction status - */ -enum GNUNET_DB_QueryStatus -TAH_PG_del_reserve_balance_insufficient_inconsistency ( - void *cls, - uint64_t row_id); - -#endif // SRC_PG_DEL_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_H diff --git a/src/auditordb/pg_del_reserve_balance_summary_wrong_inconsistency.c b/src/auditordb/pg_del_reserve_balance_summary_wrong_inconsistency.c deleted file mode 100644 index 33a31c220..000000000 --- a/src/auditordb/pg_del_reserve_balance_summary_wrong_inconsistency.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - 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 "pg_del_reserve_balance_summary_wrong_inconsistency.h" - -#include "taler_pq_lib.h" -#include "pg_helper.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_del_reserve_balance_summary_wrong_inconsistency ( - void *cls, - uint64_t row_id) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&row_id), - GNUNET_PQ_query_param_end - }; - - PREPARE (pg, - "auditor_delete_reserve_balance_summary_wrong_inconsistency", - "DELETE" - " FROM auditor_reserve_balance_summary_wrong_inconsistency" - " WHERE row_id=$1;"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "auditor_delete_reserve_balance_summary_wrong_inconsistency", - params); -} diff --git a/src/auditordb/pg_del_reserve_balance_summary_wrong_inconsistency.h b/src/auditordb/pg_del_reserve_balance_summary_wrong_inconsistency.h deleted file mode 100644 index aa08c193e..000000000 --- a/src/auditordb/pg_del_reserve_balance_summary_wrong_inconsistency.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - 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 SRC_PG_DEL_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_H -#define SRC_PG_DEL_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -/** - * Delete a row from the bad sig losses table. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param row_id row to delete - * @return query transaction status - */ -enum GNUNET_DB_QueryStatus -TAH_PG_del_reserve_balance_summary_wrong_inconsistency ( - void *cls, - uint64_t row_id); - -#endif // SRC_PG_DEL_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_H diff --git a/src/auditordb/pg_del_reserve_in_inconsistency.c b/src/auditordb/pg_del_reserve_in_inconsistency.c deleted file mode 100644 index a24f3c36e..000000000 --- a/src/auditordb/pg_del_reserve_in_inconsistency.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - 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 "pg_del_reserve_in_inconsistency.h" - -#include "taler_pq_lib.h" -#include "pg_helper.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_del_reserve_in_inconsistency ( - void *cls, - uint64_t row_id) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&row_id), - GNUNET_PQ_query_param_end - }; - - PREPARE (pg, - "auditor_delete_reserve_in_inconsistency", - "DELETE" - " FROM auditor_reserve_in_inconsistency" - " WHERE row_id=$1;"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "auditor_delete_reserve_in_inconsistency", - params); -} diff --git a/src/auditordb/pg_del_reserve_in_inconsistency.h b/src/auditordb/pg_del_reserve_in_inconsistency.h deleted file mode 100644 index 7db76b247..000000000 --- a/src/auditordb/pg_del_reserve_in_inconsistency.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - 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 SRC_PG_DEL_RESERVE_IN_INCONSISTENCY_H -#define SRC_PG_DEL_RESERVE_IN_INCONSISTENCY_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -/** - * Delete a row from the bad sig losses table. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param row_id row to delete - * @return query transaction status - */ -enum GNUNET_DB_QueryStatus -TAH_PG_del_reserve_in_inconsistency ( - void *cls, - uint64_t row_id); - -#endif // SRC_PG_DEL_RESERVE_IN_INCONSISTENCY_H diff --git a/src/auditordb/pg_del_reserve_not_closed_inconsistency.c b/src/auditordb/pg_del_reserve_not_closed_inconsistency.c deleted file mode 100644 index 25ebf7178..000000000 --- a/src/auditordb/pg_del_reserve_not_closed_inconsistency.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - 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 "pg_del_reserve_not_closed_inconsistency.h" - -#include "taler_pq_lib.h" -#include "pg_helper.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_del_reserve_not_closed_inconsistency ( - void *cls, - uint64_t row_id) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&row_id), - GNUNET_PQ_query_param_end - }; - - PREPARE (pg, - "auditor_delete_reserve_not_closed_inconsistency", - "DELETE" - " FROM auditor_reserve_not_closed_inconsistency" - " WHERE row_id=$1;"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "auditor_delete_reserve_not_closed_inconsistency", - params); -} diff --git a/src/auditordb/pg_del_reserve_not_closed_inconsistency.h b/src/auditordb/pg_del_reserve_not_closed_inconsistency.h deleted file mode 100644 index dc71fb2c3..000000000 --- a/src/auditordb/pg_del_reserve_not_closed_inconsistency.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - 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 SRC_PG_DEL_RESERVE_NOT_CLOSED_INCONSISTENCY_H -#define SRC_PG_DEL_RESERVE_NOT_CLOSED_INCONSISTENCY_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -/** - * Delete a row from the bad sig losses table. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param row_id row to delete - * @return query transaction status - */ -enum GNUNET_DB_QueryStatus -TAH_PG_del_reserve_not_closed_inconsistency ( - void *cls, - uint64_t row_id); - -#endif // SRC_PG_DEL_RESERVE_NOT_CLOSED_INCONSISTENCY_H diff --git a/src/auditordb/pg_del_reserves.c b/src/auditordb/pg_del_reserves.c deleted file mode 100644 index 731cec48f..000000000 --- a/src/auditordb/pg_del_reserves.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - 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 "pg_del_reserves.h" - -#include "taler_pq_lib.h" -#include "pg_helper.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_del_reserves ( - void *cls, - uint64_t row_id) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&row_id), - GNUNET_PQ_query_param_end - }; - - PREPARE (pg, - "auditor_delete_reserves", - "DELETE" - " FROM auditor_reserves" - " WHERE row_id=$1;"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "auditor_delete_reserves", - params); -} diff --git a/src/auditordb/pg_del_reserves.h b/src/auditordb/pg_del_reserves.h deleted file mode 100644 index 3e3136a69..000000000 --- a/src/auditordb/pg_del_reserves.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - 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 SRC_PG_DEL_RESERVES_H -#define SRC_PG_DEL_RESERVES_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -/** - * Delete a row from the bad sig losses table. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param row_id row to delete - * @return query transaction status - */ -enum GNUNET_DB_QueryStatus -TAH_PG_del_reserves ( - void *cls, - uint64_t row_id); - -#endif // SRC_PG_DEL_RESERVES_H diff --git a/src/auditordb/pg_del_row_inconsistency.c b/src/auditordb/pg_del_row_inconsistency.c deleted file mode 100644 index f4ab9e068..000000000 --- a/src/auditordb/pg_del_row_inconsistency.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - 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 "pg_del_row_inconsistency.h" -#include "taler_pq_lib.h" -#include "pg_helper.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_del_row_inconsistency ( - void *cls, - uint64_t row_id) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&row_id), - GNUNET_PQ_query_param_end - }; - - PREPARE (pg, - "auditor_delete_row_inconsistency", - "DELETE" - " FROM auditor_row_inconsistency" - " WHERE row_id=$1;"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "auditor_delete_row_inconsistency", - params); -} diff --git a/src/auditordb/pg_del_row_inconsistency.h b/src/auditordb/pg_del_row_inconsistency.h deleted file mode 100644 index 2584f5265..000000000 --- a/src/auditordb/pg_del_row_inconsistency.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - 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 SRC_PG_DEL_ROW_INCONSISTENCY_H -#define SRC_PG_DEL_ROW_INCONSISTENCY_H - -#include "taler_util.h" -#include "taler_json_lib.h" -#include "taler_auditordb_plugin.h" - -/** - * Delete a row from the deposit confirmations table. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param row_id row to delete - * @return query transaction status - */ -enum GNUNET_DB_QueryStatus -TAH_PG_del_row_inconsistency ( - void *cls, - uint64_t row_id); - -#endif // SRC_PG_DEL_ROW_INCONSISTENCY_H diff --git a/src/auditordb/pg_del_row_minor_inconsistencies.c b/src/auditordb/pg_del_row_minor_inconsistencies.c deleted file mode 100644 index 00d8d58e8..000000000 --- a/src/auditordb/pg_del_row_minor_inconsistencies.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - 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 "pg_del_row_minor_inconsistencies.h" - -#include "taler_pq_lib.h" -#include "pg_helper.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_del_row_minor_inconsistencies ( - void *cls, - uint64_t row_id) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&row_id), - GNUNET_PQ_query_param_end - }; - - PREPARE (pg, - "auditor_delete_row_minor_inconsistencies", - "DELETE" - " FROM auditor_row_minor_inconsistencies" - " WHERE row_id=$1;"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "auditor_delete_row_minor_inconsistencies", - params); -} diff --git a/src/auditordb/pg_del_row_minor_inconsistencies.h b/src/auditordb/pg_del_row_minor_inconsistencies.h deleted file mode 100644 index 06b719cd3..000000000 --- a/src/auditordb/pg_del_row_minor_inconsistencies.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - 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 SRC_PG_DEL_ROW_MINOR_INCONSISTENCIES_H -#define SRC_PG_DEL_ROW_MINOR_INCONSISTENCIES_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -/** - * Delete a row from the bad sig losses table. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param row_id row to delete - * @return query transaction status - */ -enum GNUNET_DB_QueryStatus -TAH_PG_del_row_minor_inconsistencies ( - void *cls, - uint64_t row_id); - -#endif // SRC_PG_DEL_ROW_MINOR_INCONSISTENCIES_H diff --git a/src/auditordb/pg_del_wire_format_inconsistency.c b/src/auditordb/pg_del_wire_format_inconsistency.c deleted file mode 100644 index ec55a8bb6..000000000 --- a/src/auditordb/pg_del_wire_format_inconsistency.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - 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 "pg_del_wire_format_inconsistency.h" - -#include "taler_pq_lib.h" -#include "pg_helper.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_del_wire_format_inconsistency ( - void *cls, - uint64_t row_id) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&row_id), - GNUNET_PQ_query_param_end - }; - - PREPARE (pg, - "auditor_delete_wire_format_inconsistency", - "DELETE" - " FROM auditor_wire_format_inconsistency" - " WHERE row_id=$1;"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "auditor_delete_wire_format_inconsistency", - params); -} diff --git a/src/auditordb/pg_del_wire_format_inconsistency.h b/src/auditordb/pg_del_wire_format_inconsistency.h deleted file mode 100644 index ca7384180..000000000 --- a/src/auditordb/pg_del_wire_format_inconsistency.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - 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 SRC_PG_DEL_WIRE_FORMAT_INCONSISTENCY_H -#define SRC_PG_DEL_WIRE_FORMAT_INCONSISTENCY_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -/** - * Delete a row from the bad sig losses table. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param row_id row to delete - * @return query transaction status - */ -enum GNUNET_DB_QueryStatus -TAH_PG_del_wire_format_inconsistency ( - void *cls, - uint64_t row_id); - -#endif // SRC_PG_DEL_WIRE_FORMAT_INCONSISTENCY_H diff --git a/src/auditordb/pg_del_wire_out_inconsistency.c b/src/auditordb/pg_del_wire_out_inconsistency.c deleted file mode 100644 index 1e318a5be..000000000 --- a/src/auditordb/pg_del_wire_out_inconsistency.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - 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 "pg_del_wire_out_inconsistency.h" - -#include "taler_pq_lib.h" -#include "pg_helper.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_del_wire_out_inconsistency ( - void *cls, - uint64_t row_id) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&row_id), - GNUNET_PQ_query_param_end - }; - - PREPARE (pg, - "auditor_delete_wire_out_inconsistency", - "DELETE" - " FROM auditor_wire_out_inconsistency" - " WHERE row_id=$1;"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "auditor_delete_wire_out_inconsistency", - params); -} diff --git a/src/auditordb/pg_del_wire_out_inconsistency.h b/src/auditordb/pg_del_wire_out_inconsistency.h deleted file mode 100644 index 759459424..000000000 --- a/src/auditordb/pg_del_wire_out_inconsistency.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - 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 SRC_PG_DEL_WIRE_OUT_INCONSISTENCY_H -#define SRC_PG_DEL_WIRE_OUT_INCONSISTENCY_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -/** - * Delete a row from the bad sig losses table. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param row_id row to delete - * @return query transaction status - */ -enum GNUNET_DB_QueryStatus -TAH_PG_del_wire_out_inconsistency ( - void *cls, - uint64_t row_id); - -#endif // SRC_PG_DEL_WIRE_OUT_INCONSISTENCY_H diff --git a/src/auditordb/pg_delete_deposit_confirmations.c b/src/auditordb/pg_delete_deposit_confirmations.c deleted file mode 100644 index b337239c8..000000000 --- a/src/auditordb/pg_delete_deposit_confirmations.c +++ /dev/null @@ -1,47 +0,0 @@ -/*
- 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 auditordb/pg_delete_deposit_confirmations.c
- * @brief Implementation of the delete_deposit_confirmations function for Postgres
- * @author Nicola Eigel
- */
-#include "platform.h"
-#include "taler_error_codes.h"
-#include "taler_dbevents.h"
-#include "taler_pq_lib.h"
-#include "pg_delete_deposit_confirmations.h"
-#include "pg_helper.h"
-
-enum GNUNET_DB_QueryStatus
-TAH_PG_delete_deposit_confirmation (
- void *cls,
- uint64_t row_id)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&row_id),
- GNUNET_PQ_query_param_end
- };
-
- PREPARE (pg,
- "auditor_delete_deposit_confirmation",
- "DELETE"
- " FROM auditor_deposit_confirmations"
- " WHERE deposit_confirmation_serial_id=$1;");
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "auditor_delete_deposit_confirmation",
- params);
-}
diff --git a/src/auditordb/pg_delete_generic.c b/src/auditordb/pg_delete_generic.c new file mode 100644 index 000000000..800004465 --- /dev/null +++ b/src/auditordb/pg_delete_generic.c @@ -0,0 +1,85 @@ +/* + 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 "platform.h" +#include "taler_pq_lib.h" +#include "pg_helper.h" +#include "pg_delete_generic.h" + +struct Preparations +{ + /** + * Database reconnect counter. + */ + unsigned long long cnt; + + /** + * Which DB did we do prepare for. + */ + struct PostgresClosure *pg; + +}; + +enum GNUNET_DB_QueryStatus +TAH_PG_delete_generic ( + void *cls, + enum TALER_AUDITORDB_DeletableSuppressableTables table, + uint64_t row_id) +{ + struct PostgresClosure *pg = cls; + 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 = TAH_PG_get_deletable_suppressable_table_name(table); + char statement_name[256]; + + GNUNET_snprintf (statement_name, + sizeof (statement_name), + "delete_%s", + table_name); + if ( (pg != prep->pg) || + (prep->cnt < pg->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 (pg->conn, + ps)) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + prep->pg = pg; + prep->cnt = pg->prep_gen; + } + return GNUNET_PQ_eval_prepared_non_select (pg->conn, + statement_name, + params); +} diff --git a/src/auditordb/pg_del_emergency.h b/src/auditordb/pg_delete_generic.h index 91cef7363..c37a403c1 100644 --- a/src/auditordb/pg_del_emergency.h +++ b/src/auditordb/pg_delete_generic.h @@ -13,23 +13,26 @@ You should have 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 SRC_PG_DEL_EMERGENCY_H -#define SRC_PG_DEL_EMERGENCY_H +/** + * @file pg_delete_generic.h + * @brief implementation of the delete_generic function + * @author Nic Eigel + */ +#ifndef PG_DELETE_GENERIC_H +#define PG_DELETE_GENERIC_H #include "taler_util.h" +#include "taler_json_lib.h" #include "taler_auditordb_plugin.h" /** - * Delete a row from the denom key validity withdraw inconsistency table. - * - * @param cls the plugin-specific state - * @param row_id row to delete - * @return query transaction status + // FIXME: add comments + * @return transaction status code */ enum GNUNET_DB_QueryStatus -TAH_PG_del_emergency ( +TAH_PG_delete_generic ( void *cls, + enum TALER_AUDITORDB_DeletableSuppressableTables table, uint64_t row_id); #endif diff --git a/src/auditordb/pg_delete_wire_out_inconsistency_if_matching.c b/src/auditordb/pg_delete_wire_out_inconsistency_if_matching.c new file mode 100644 index 000000000..3e959bf5d --- /dev/null +++ b/src/auditordb/pg_delete_wire_out_inconsistency_if_matching.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 "platform.h" +#include "taler_pq_lib.h" +#include "pg_helper.h" +#include "pg_delete_wire_out_inconsistency_if_matching.h" + + +enum GNUNET_DB_QueryStatus +TAH_PG_delete_wire_out_inconsistency_if_matching ( + void *cls, + const struct TALER_AUDITORDB_WireOutInconsistency *dc) +{ + struct PostgresClosure *pg = cls; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (dc->destination_account), + GNUNET_PQ_query_param_string (dc->diagnostic), + GNUNET_PQ_query_param_uint64 (&dc->wire_out_row_id), + TALER_PQ_query_param_amount (pg->conn, + &dc->expected), + TALER_PQ_query_param_amount (pg->conn, + &dc->claimed), + GNUNET_PQ_query_param_end + }; + + PREPARE (pg, + "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 ( + pg->conn, + "auditor_wire_out_inconsistency_delete_if_matching", + params); +} diff --git a/src/auditordb/pg_del_emergency_by_count.h b/src/auditordb/pg_delete_wire_out_inconsistency_if_matching.h index 52f7f4db8..b81bc418c 100644 --- a/src/auditordb/pg_del_emergency_by_count.h +++ b/src/auditordb/pg_delete_wire_out_inconsistency_if_matching.h @@ -13,23 +13,23 @@ You should have 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 SRC_PG_DEL_EMERGENCY_BY_COUNT_H -#define SRC_PG_DEL_EMERGENCY_BY_COUNT_H +#ifndef PG_DELETE_WIRE_OUT_INCONSISTENCY_IF_MATCHING_H +#define PG_DELETE_WIRE_OUT_INCONSISTENCY_IF_MATCHING_H #include "taler_util.h" #include "taler_auditordb_plugin.h" + /** - * Delete a row from the emergency by count table. + * Delete information about a bad sig loss into the database. * * @param cls the @e cls of this struct with the plugin-specific state - * @param row_id row to delete - * @return query transaction status + * @param dc deposit confirmation information to store + * @return query result status */ enum GNUNET_DB_QueryStatus -TAH_PG_del_emergency_by_count ( +TAH_PG_delete_wire_out_inconsistency_if_matching ( void *cls, - uint64_t row_id); + const struct TALER_AUDITORDB_WireOutInconsistency *dc); #endif diff --git a/src/auditordb/pg_get_amount_arithmetic_inconsistency.c b/src/auditordb/pg_get_amount_arithmetic_inconsistency.c index 4b09ee39b..5bd9a284a 100644 --- a/src/auditordb/pg_get_amount_arithmetic_inconsistency.c +++ b/src/auditordb/pg_get_amount_arithmetic_inconsistency.c @@ -13,7 +13,6 @@ You should have 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 "platform.h" #include "taler_error_codes.h" #include "taler_dbevents.h" @@ -68,14 +67,12 @@ amount_arithmetic_inconsistency_cb (void *cls, for (unsigned int i = 0; i < num_results; i++) { - uint64_t serial_id; - struct TALER_AUDITORDB_AmountArithmeticInconsistency dc; - struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_uint64 ("row_id", - &serial_id), - // TODO: what type is this exactly + &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", @@ -84,7 +81,8 @@ amount_arithmetic_inconsistency_cb (void *cls, &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; @@ -98,11 +96,8 @@ amount_arithmetic_inconsistency_cb (void *cls, 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) @@ -116,13 +111,12 @@ TAH_PG_get_amount_arithmetic_inconsistency ( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, // maybe not needed + bool return_suppressed, TALER_AUDITORDB_AmountArithmeticInconsistencyCallback cb, void *cb_cls) { - uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); - struct PostgresClosure *pg = 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), @@ -140,13 +134,15 @@ TAH_PG_get_amount_arithmetic_inconsistency ( "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 suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id DESC" " LIMIT $3" ); @@ -154,28 +150,28 @@ TAH_PG_get_amount_arithmetic_inconsistency ( "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 suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id ASC" " LIMIT $3" ); - qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, - (limit > 0) ? - "auditor_amount_arithmetic_inconsistency_select_asc" - : - "auditor_amount_arithmetic_inconsistency_select_desc", - params, - &amount_arithmetic_inconsistency_cb, - &dcc); - - + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->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; -}
\ No newline at end of file +} diff --git a/src/auditordb/pg_get_auditor_closure_lags.c b/src/auditordb/pg_get_auditor_closure_lags.c index e13fe1319..de2b98dd6 100644 --- a/src/auditordb/pg_get_auditor_closure_lags.c +++ b/src/auditordb/pg_get_auditor_closure_lags.c @@ -13,13 +13,11 @@ You should have 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 "platform.h" #include "taler_error_codes.h" #include "taler_dbevents.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_get_auditor_closure_lags.h" @@ -67,17 +65,22 @@ closure_lags_cb (void *cls, for (unsigned int i = 0; i < num_results; i++) { - uint64_t serial_id; - struct TALER_AUDITORDB_ClosureLags dc; - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_uint64 ("row_id", &serial_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), - + 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), + GNUNET_PQ_result_spec_bool ("suppressed", + &dc.suppressed), GNUNET_PQ_result_spec_end }; enum GNUNET_GenericReturnValue rval; @@ -91,11 +94,8 @@ closure_lags_cb (void *cls, 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) @@ -109,21 +109,18 @@ TAH_PG_get_auditor_closure_lags ( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, // maybe not needed + bool return_suppressed, TALER_AUDITORDB_ClosureLagsCallback cb, void *cb_cls) { - - uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); - struct PostgresClosure *pg = 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, @@ -135,13 +132,15 @@ TAH_PG_get_auditor_closure_lags ( "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 suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id DESC" " LIMIT $3" ); @@ -149,25 +148,26 @@ TAH_PG_get_auditor_closure_lags ( "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 suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id ASC" " LIMIT $3" ); - qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, - (limit > 0) ? - "auditor_auditor_closure_lags_get_asc" - : - "auditor_auditor_closure_lags_get_desc", - params, - &closure_lags_cb, - &dcc); - + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->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); diff --git a/src/auditordb/pg_get_auditor_progress.c b/src/auditordb/pg_get_auditor_progress.c index 3742d2eb6..b13842b1d 100644 --- a/src/auditordb/pg_get_auditor_progress.c +++ b/src/auditordb/pg_get_auditor_progress.c @@ -75,7 +75,7 @@ auditor_progress_cb (void *cls, { struct AuditorProgressContext *ctx = cls; - GNUNET_assert (num_results <= ctx->len); + GNUNET_assert (num_results == ctx->len); for (unsigned int i = 0; i < num_results; i++) { bool is_missing = false; @@ -142,7 +142,6 @@ TAH_PG_get_auditor_progress (void *cls, keys[0] = progress_key; dsts[0] = progress_offset; - va_start (ap, progress_offset); while (off < cnt) @@ -163,6 +162,7 @@ TAH_PG_get_auditor_progress (void *cls, " 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 (pg->conn, "get_auditor_progress", params, @@ -173,6 +173,7 @@ TAH_PG_get_auditor_progress (void *cls, return GNUNET_DB_STATUS_HARD_ERROR; if (qs < 0) return qs; + GNUNET_assert (ctx.off == cnt); return qs; } } diff --git a/src/auditordb/pg_get_bad_sig_losses.c b/src/auditordb/pg_get_bad_sig_losses.c index 096739779..f28bedc60 100644 --- a/src/auditordb/pg_get_bad_sig_losses.c +++ b/src/auditordb/pg_get_bad_sig_losses.c @@ -13,14 +13,11 @@ You should have 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 "platform.h" #include "taler_error_codes.h" #include "taler_dbevents.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_get_bad_sig_losses.h" @@ -65,23 +62,23 @@ bad_sig_losses_cb (void *cls, { struct BadSigLossesContext *dcc = cls; struct PostgresClosure *pg = dcc->pg; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "---found badsiglosses...\n"); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "---num_results: %u\n", num_results); for (unsigned int i = 0; i < num_results; i++) { - uint64_t serial_id; - struct TALER_AUDITORDB_BadSigLosses 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 ("loss", &dc.loss), + 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; @@ -95,11 +92,8 @@ bad_sig_losses_cb (void *cls, 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) @@ -114,41 +108,23 @@ TAH_PG_get_bad_sig_losses ( int64_t limit, uint64_t offset, bool return_suppressed, - bool filter_spec_pub, - struct GNUNET_CRYPTO_EddsaPublicKey op_spec_pub, + const struct GNUNET_CRYPTO_EddsaPublicKey *op_spec_pub, const char *op, TALER_AUDITORDB_BadSigLossesCallback cb, void *cb_cls) { - - /*if true, does not filter for an operation specific key*/ - bool any_spec_pub = ! filter_spec_pub; - - /*if true, does not filter for an operation*/ - bool any_op = true; - const char *o; - - if (op != NULL) - { - any_op = false; - o = op; - } - else - { - o = ""; - } - - uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); - struct PostgresClosure *pg = 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_bool (any_spec_pub), - GNUNET_PQ_query_param_auto_from_type (&op_spec_pub), - GNUNET_PQ_query_param_bool (any_op), - GNUNET_PQ_query_param_string (o), + 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 = { @@ -162,14 +138,16 @@ TAH_PG_get_bad_sig_losses ( "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 suppressed is false)" - " AND ($4 OR operation_specific_pub = $5)" - " AND ($6 OR operation = $7)" + " 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" ); @@ -177,27 +155,29 @@ TAH_PG_get_bad_sig_losses ( "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 suppressed is false)" - " AND ($4 OR operation_specific_pub = $5)" - " AND ($6 OR operation = $7)" + " 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 (pg->conn, - (limit > 0) - ? "auditor_bad_sig_losses_get_asc" - : "auditor_bad_sig_losses_get_desc", - params, - &bad_sig_losses_cb, - &dcc); - + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->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; -}
\ No newline at end of file +} diff --git a/src/auditordb/pg_get_bad_sig_losses.h b/src/auditordb/pg_get_bad_sig_losses.h index 8cf04eddd..45d871636 100644 --- a/src/auditordb/pg_get_bad_sig_losses.h +++ b/src/auditordb/pg_get_bad_sig_losses.h @@ -13,9 +13,8 @@ You should have 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 SRC_PG_GET_BAD_SIG_LOSSES_H -#define SRC_PG_GET_BAD_SIG_LOSSES_H +#ifndef PG_GET_BAD_SIG_LOSSES_H +#define PG_GET_BAD_SIG_LOSSES_H #include "taler_util.h" #include "taler_json_lib.h" @@ -28,7 +27,6 @@ * @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 filter_spec_pub filter by @a op_spec_pub * @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 @@ -41,8 +39,7 @@ TAH_PG_get_bad_sig_losses ( int64_t limit, uint64_t offset, bool return_suppressed, - bool filter_spec_pub, - struct GNUNET_CRYPTO_EddsaPublicKey op_spec_pub, + const struct GNUNET_CRYPTO_EddsaPublicKey *op_spec_pub, const char *op, TALER_AUDITORDB_BadSigLossesCallback cb, void *cb_cls); diff --git a/src/auditordb/pg_get_balance.c b/src/auditordb/pg_get_balance.c index 2bacbb507..d7e1816d9 100644 --- a/src/auditordb/pg_get_balance.c +++ b/src/auditordb/pg_get_balance.c @@ -80,7 +80,7 @@ balance_cb (void *cls, GNUNET_assert (num_results <= ctx->len); for (unsigned int i = 0; i < num_results; i++) { - bool is_missing = false; + bool is_missing; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_allow_null ( TALER_PQ_result_spec_amount ("balance", @@ -101,8 +101,9 @@ balance_cb (void *cls, } if (is_missing) { - TALER_amount_set_zero (pg->currency, - ctx->dst[i]); + GNUNET_assert (GNUNET_OK == + TALER_amount_set_zero (pg->currency, + ctx->dst[i])); } ctx->off++; } @@ -119,14 +120,22 @@ TAH_PG_get_balance (void *cls, unsigned int cnt = 1; va_list ap; + GNUNET_assert (GNUNET_OK == + TALER_amount_set_zero (pg->currency, + balance_value)); va_start (ap, balance_value); while (NULL != va_arg (ap, const char *)) { + struct TALER_Amount *dst; + cnt++; - (void) va_arg (ap, - struct TALER_Amount *); + dst = va_arg (ap, + struct TALER_Amount *); + GNUNET_assert (GNUNET_OK == + TALER_amount_set_zero (pg->currency, + dst)); } va_end (ap); { @@ -148,7 +157,6 @@ TAH_PG_get_balance (void *cls, keys[0] = balance_key; dsts[0] = balance_value; - va_start (ap, balance_value); while (off < cnt) diff --git a/src/auditordb/pg_get_balances.c b/src/auditordb/pg_get_balances.c index 8f8f2d682..4ddb9eb49 100644 --- a/src/auditordb/pg_get_balances.c +++ b/src/auditordb/pg_get_balances.c @@ -13,14 +13,11 @@ You should have 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 "platform.h" #include "taler_error_codes.h" #include "taler_dbevents.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_get_balances.h" @@ -68,18 +65,12 @@ balances_cb (void *cls, for (unsigned int i = 0; i < num_results; i++) { - uint64_t serial_id; - struct TALER_AUDITORDB_Balances dc; - struct GNUNET_PQ_ResultSpec rs[] = { - - GNUNET_PQ_result_spec_uint64 ("row_id", &serial_id), - - GNUNET_PQ_result_spec_string ("balance_key", &dc.balance_key), - TALER_PQ_RESULT_SPEC_AMOUNT ("balance_value", &dc.balance_value), - - + 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; @@ -93,11 +84,8 @@ balances_cb (void *cls, 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) @@ -109,37 +97,15 @@ balances_cb (void *cls, enum GNUNET_DB_QueryStatus TAH_PG_get_balances ( void *cls, - int64_t limit, - uint64_t offset, - bool return_suppressed, const char *balance_key, TALER_AUDITORDB_BalancesCallback cb, void *cb_cls) { - - - /*if true, does not filter for a specific balance*/ - bool any_balance = true; - const char *bk; - - if (balance_key != NULL) - { - any_balance = false; - bk = balance_key; - } - else - { - bk = ""; - } - - uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); - struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&offset), - GNUNET_PQ_query_param_uint64 (&plimit), - GNUNET_PQ_query_param_bool (any_balance), - GNUNET_PQ_query_param_string (bk), + NULL == balance_key + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (balance_key), GNUNET_PQ_query_param_end }; struct BalancesContext dcc = { @@ -150,37 +116,19 @@ TAH_PG_get_balances ( enum GNUNET_DB_QueryStatus qs; PREPARE (pg, - "auditor_balances_get_desc", - "SELECT" - " row_id," - " balance_key," - " balance_value" - " FROM auditor_balances" - " WHERE (row_id < $1)" - " AND ($3 OR balance_key = $4)" - " ORDER BY row_id DESC" - " LIMIT $2" - ); - PREPARE (pg, - "auditor_balances_get_asc", + "auditor_balances_get", "SELECT" - " row_id," - " balance_key," - " balance_value" + " balance_key" + ",balance_value" " FROM auditor_balances" - " WHERE (row_id > $1)" - " AND ($3 OR balance_key = $4)" - " ORDER BY row_id ASC" - " LIMIT $2" + " WHERE ($1::TEXT IS NULL OR balance_key = $1)" ); - qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, - (limit > 0) - ? "auditor_balances_get_asc" - : "auditor_balances_get_desc", - params, - &balances_cb, - &dcc); - + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->conn, + "auditor_balances_get", + params, + &balances_cb, + &dcc); if (qs > 0) return dcc.qs; GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); diff --git a/src/auditordb/pg_get_balances.h b/src/auditordb/pg_get_balances.h index e2883ad8f..affc20072 100644 --- a/src/auditordb/pg_get_balances.h +++ b/src/auditordb/pg_get_balances.h @@ -13,24 +13,18 @@ You should have 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 SRC_PG_GET_BALANCES_H -#define SRC_PG_GET_BALANCES_H +#ifndef PG_GET_BALANCES_H +#define PG_GET_BALANCES_H #include "taler_util.h" #include "taler_json_lib.h" #include "taler_auditordb_plugin.h" - /** * Get information about balances 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 balance_key key to look for + * @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 @@ -38,9 +32,6 @@ enum GNUNET_DB_QueryStatus TAH_PG_get_balances ( void *cls, - int64_t limit, - uint64_t offset, - bool return_suppressed, const char *balance_key, TALER_AUDITORDB_BalancesCallback cb, void *cb_cls); diff --git a/src/auditordb/pg_get_denomination_key_validity_withdraw_inconsistency.c b/src/auditordb/pg_get_denomination_key_validity_withdraw_inconsistency.c index 7449f35da..c1b6a9a50 100644 --- a/src/auditordb/pg_get_denomination_key_validity_withdraw_inconsistency.c +++ b/src/auditordb/pg_get_denomination_key_validity_withdraw_inconsistency.c @@ -13,16 +13,14 @@ You should have 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 "platform.h" #include "taler_error_codes.h" #include "taler_dbevents.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_get_denomination_key_validity_withdraw_inconsistency.h" + /** * Closure for #denomination_key_validity_withdraw_inconsistency_cb(). */ @@ -69,18 +67,20 @@ denomination_key_validity_withdraw_inconsistency_cb (void *cls, for (unsigned int i = 0; i < num_results; i++) { - uint64_t serial_id; - struct TALER_AUDITORDB_DenominationKeyValidityWithdrawInconsistency dc; - struct GNUNET_PQ_ResultSpec rs[] = { - - GNUNET_PQ_result_spec_uint64 ("row_id", &serial_id), + 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_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; @@ -94,11 +94,8 @@ denomination_key_validity_withdraw_inconsistency_cb (void *cls, 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) @@ -112,15 +109,12 @@ TAH_PG_get_denomination_key_validity_withdraw_inconsistency ( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, // maybe not needed - TALER_AUDITORDB_DenominationKeyValidityWithdrawInconsistencyCallback - cb, + bool return_suppressed, + TALER_AUDITORDB_DenominationKeyValidityWithdrawInconsistencyCallback cb, void *cb_cls) { - - uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); - struct PostgresClosure *pg = 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), @@ -138,12 +132,14 @@ TAH_PG_get_denomination_key_validity_withdraw_inconsistency ( "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 suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id DESC" " LIMIT $3" ); @@ -151,27 +147,27 @@ TAH_PG_get_denomination_key_validity_withdraw_inconsistency ( "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 suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id ASC" " LIMIT $3" ); - qs = GNUNET_PQ_eval_prepared_multi_select (pg->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); - + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->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; -}
\ No newline at end of file +} diff --git a/src/auditordb/pg_get_denomination_pending.c b/src/auditordb/pg_get_denomination_pending.c index 02ef99fe2..09276962c 100644 --- a/src/auditordb/pg_get_denomination_pending.c +++ b/src/auditordb/pg_get_denomination_pending.c @@ -13,14 +13,11 @@ You should have 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 "platform.h" #include "taler_error_codes.h" #include "taler_dbevents.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_get_denomination_pending.h" @@ -71,14 +68,20 @@ denomination_pending_cb (void *cls, 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_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), + 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; @@ -108,14 +111,11 @@ TAH_PG_get_denomination_pending ( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, // maybe not needed TALER_AUDITORDB_DenominationPendingCallback cb, void *cb_cls) { - - uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); - struct PostgresClosure *pg = 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), @@ -141,7 +141,7 @@ TAH_PG_get_denomination_pending ( " FROM auditor_denomination_pending" " WHERE (row_id < $1)" " ORDER BY row_id DESC" - " LIMIT $3" + " LIMIT $2" ); PREPARE (pg, "auditor_denomination_pending_get_asc", @@ -156,18 +156,16 @@ TAH_PG_get_denomination_pending ( " FROM auditor_denomination_pending" " WHERE (row_id > $1)" " ORDER BY row_id ASC" - " LIMIT $3" + " LIMIT $2" ); - qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, - (limit > 0) - ? - "auditor_denomination_pending_get_asc" - : - "auditor_denomination_pending_get_desc", - params, - &denomination_pending_cb, - &dcc); - + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->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); diff --git a/src/auditordb/pg_get_denomination_pending.h b/src/auditordb/pg_get_denomination_pending.h index 478c3248c..f951a2c1b 100644 --- a/src/auditordb/pg_get_denomination_pending.h +++ b/src/auditordb/pg_get_denomination_pending.h @@ -13,10 +13,8 @@ You should have 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 SRC_PG_GET_DENOMINATION_PENDING_H -#define SRC_PG_GET_DENOMINATION_PENDING_H +#ifndef PG_GET_DENOMINATION_PENDING_H +#define PG_GET_DENOMINATION_PENDING_H #include "taler_util.h" #include "taler_json_lib.h" @@ -28,7 +26,6 @@ * @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 @@ -38,7 +35,6 @@ TAH_PG_get_denomination_pending ( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, TALER_AUDITORDB_DenominationPendingCallback cb, void *cb_cls); diff --git a/src/auditordb/pg_get_denominations_without_sigs.c b/src/auditordb/pg_get_denominations_without_sigs.c index 2bc3e5dc0..d12f00971 100644 --- a/src/auditordb/pg_get_denominations_without_sigs.c +++ b/src/auditordb/pg_get_denominations_without_sigs.c @@ -13,14 +13,11 @@ You should have 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 "platform.h" #include "taler_error_codes.h" #include "taler_dbevents.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_get_denominations_without_sigs.h" @@ -68,21 +65,20 @@ denominations_without_sigs_cb (void *cls, for (unsigned int i = 0; i < num_results; i++) { - uint64_t serial_id; - struct TALER_AUDITORDB_DenominationsWithoutSigs dc; - struct GNUNET_PQ_ResultSpec rs[] = { - - GNUNET_PQ_result_spec_uint64 ("row_id", &serial_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_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; @@ -100,7 +96,6 @@ denominations_without_sigs_cb (void *cls, dcc->qs = i + 1; rval = dcc->cb (dcc->cb_cls, - serial_id, &dc); GNUNET_PQ_cleanup_result (rs); if (GNUNET_OK != rval) @@ -114,14 +109,12 @@ TAH_PG_get_denominations_without_sigs ( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, // maybe not needed + bool return_suppressed, TALER_AUDITORDB_DenominationsWithoutSigsCallback cb, void *cb_cls) { - - uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); - struct PostgresClosure *pg = 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), @@ -146,7 +139,7 @@ TAH_PG_get_denominations_without_sigs ( " suppressed" " FROM auditor_denominations_without_sigs" " WHERE (row_id < $1)" - " AND ($2 OR suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id DESC" " LIMIT $3" ); @@ -161,20 +154,18 @@ TAH_PG_get_denominations_without_sigs ( " suppressed" " FROM auditor_denominations_without_sigs" " WHERE (row_id > $1)" - " AND ($2 OR suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id ASC" " LIMIT $3" ); - qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, - (limit > 0) - ? - "auditor_denominations_without_sigs_get_asc" - : - "auditor_denominations_without_sigs_get_desc", - params, - &denominations_without_sigs_cb, - &dcc); - + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->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); diff --git a/src/auditordb/pg_get_deposit_confirmations.c b/src/auditordb/pg_get_deposit_confirmations.c index de9817919..f1f28b8a2 100644 --- a/src/auditordb/pg_get_deposit_confirmations.c +++ b/src/auditordb/pg_get_deposit_confirmations.c @@ -74,23 +74,20 @@ deposit_confirmation_cb (void *cls, for (unsigned int i = 0; i < num_results; i++) { - uint64_t serial_id; 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 ("deposit_confirmation_serial_id", - &serial_id), - + 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", @@ -99,7 +96,6 @@ deposit_confirmation_cb (void *cls, &dc.wire_deadline), TALER_PQ_RESULT_SPEC_AMOUNT ("total_without_fee", &dc.total_without_fee), - GNUNET_PQ_result_spec_auto_array_from_type (pg->conn, "coin_pubs", &num_pubs, @@ -116,7 +112,8 @@ deposit_confirmation_cb (void *cls, &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; @@ -142,7 +139,6 @@ deposit_confirmation_cb (void *cls, dc.coin_sigs = coin_sigs; dc.num_coins = num_sigs; rval = dcc->cb (dcc->cb_cls, - serial_id, &dc); GNUNET_PQ_cleanup_result (rs); if (GNUNET_OK != rval) @@ -160,10 +156,8 @@ TAH_PG_get_deposit_confirmations ( TALER_AUDITORDB_DepositConfirmationCallback cb, void *cb_cls) { - - uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); - struct PostgresClosure *pg = 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), @@ -180,7 +174,7 @@ TAH_PG_get_deposit_confirmations ( PREPARE (pg, "auditor_deposit_confirmation_select_desc", "SELECT" - " deposit_confirmation_serial_id" + " row_id" ",h_contract_terms" ",h_policy" ",h_wire" @@ -194,16 +188,17 @@ TAH_PG_get_deposit_confirmations ( ",exchange_sig" ",exchange_pub" ",master_sig" + ",suppressed" " FROM auditor_deposit_confirmations" - " WHERE (deposit_confirmation_serial_id < $1)" - " AND ($2 OR suppressed is false)" - " ORDER BY deposit_confirmation_serial_id DESC" + " WHERE (row_id < $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id DESC" " LIMIT $3" ); PREPARE (pg, "auditor_deposit_confirmation_select_asc", "SELECT" - " deposit_confirmation_serial_id" + " row_id" ",h_contract_terms" ",h_policy" ",h_wire" @@ -217,20 +212,21 @@ TAH_PG_get_deposit_confirmations ( ",exchange_sig" ",exchange_pub" ",master_sig" + ",suppressed" " FROM auditor_deposit_confirmations" - " WHERE (deposit_confirmation_serial_id > $1)" - " AND ($2 OR suppressed is false)" - " ORDER BY deposit_confirmation_serial_id ASC" + " WHERE (row_id > $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id ASC" " LIMIT $3" ); - qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, - (limit > 0) ? - "auditor_deposit_confirmation_select_asc" - : - "auditor_deposit_confirmation_select_desc", - params, - &deposit_confirmation_cb, - &dcc); + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->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); diff --git a/src/auditordb/pg_get_emergency.c b/src/auditordb/pg_get_emergency.c index a1e615ab2..0371e372d 100644 --- a/src/auditordb/pg_get_emergency.c +++ b/src/auditordb/pg_get_emergency.c @@ -13,14 +13,11 @@ You should have 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 "platform.h" #include "taler_error_codes.h" #include "taler_dbevents.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_get_emergency.h" /** @@ -70,18 +67,24 @@ emergency_cb (void *cls, for (unsigned int i = 0; i < num_results; i++) { - uint64_t serial_id; - struct TALER_AUDITORDB_Emergency dc; - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_uint64 ("row_id", &serial_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_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; @@ -95,11 +98,8 @@ emergency_cb (void *cls, 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) @@ -113,16 +113,15 @@ TAH_PG_get_emergency ( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, // maybe not needed + bool return_suppressed, TALER_AUDITORDB_EmergencyCallback cb, void *cb_cls) { - - uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); - struct PostgresClosure *pg = 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 }; @@ -143,10 +142,12 @@ TAH_PG_get_emergency ( ",deposit_start" ",deposit_end" ",value" + ",suppressed" " FROM auditor_emergency" " WHERE (row_id < $1)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id DESC" - " LIMIT $2" + " LIMIT $3" ); PREPARE (pg, "auditor_emergency_get_asc", @@ -158,21 +159,24 @@ TAH_PG_get_emergency ( ",deposit_start" ",deposit_end" ",value" + ",suppressed" " FROM auditor_emergency" " WHERE (row_id > $1)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id ASC" - " LIMIT $2" + " LIMIT $3" ); - qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, - (limit > 0) ? - "auditor_emergency_get_asc" : - "auditor_emergency_get_desc", - params, - &emergency_cb, - &dcc); + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->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; -}
\ No newline at end of file +} diff --git a/src/auditordb/pg_get_emergency_by_count.c b/src/auditordb/pg_get_emergency_by_count.c index eecc6594e..60d434b9b 100644 --- a/src/auditordb/pg_get_emergency_by_count.c +++ b/src/auditordb/pg_get_emergency_by_count.c @@ -13,16 +13,14 @@ You should have 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 "platform.h" #include "taler_error_codes.h" #include "taler_dbevents.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_get_emergency_by_count.h" + /** * Closure for #emergency_cb(). */ @@ -70,17 +68,26 @@ emergency_by_count_cb (void *cls, for (unsigned int i = 0; i < num_results; i++) { - uint64_t serial_id; struct TALER_AUDITORDB_EmergenciesByCount dc; struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_uint64 ("row_id", &serial_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_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; @@ -96,7 +103,6 @@ emergency_by_count_cb (void *cls, } dcc->qs = i + 1; rval = dcc->cb (dcc->cb_cls, - serial_id, &dc); GNUNET_PQ_cleanup_result (rs); if (GNUNET_OK != rval) @@ -110,12 +116,12 @@ TAH_PG_get_emergency_by_count ( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, // maybe not needed + bool return_suppressed, TALER_AUDITORDB_EmergenciesByCountCallback cb, void *cb_cls) { - uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); struct PostgresClosure *pg = 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), @@ -140,9 +146,10 @@ TAH_PG_get_emergency_by_count ( ",start" ",deposit_end" ",value" + ",suppressed" " FROM auditor_emergency_by_count" " WHERE (row_id < $1)" - " AND ($2 OR suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id DESC" " LIMIT $3" ); @@ -157,21 +164,21 @@ TAH_PG_get_emergency_by_count ( ",start" ",deposit_end" ",value" + ",suppressed" " FROM auditor_emergency_by_count" " WHERE (row_id > $1)" - " AND ($2 OR suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id ASC" " LIMIT $3" ); - qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, - (limit > 0) - ? - "auditor_emergency_by_count_get_asc" - : - "auditor_emergency_by_count_get_desc", - params, - &emergency_by_count_cb, - &dcc); + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->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); diff --git a/src/auditordb/pg_get_fee_time_inconsistency.c b/src/auditordb/pg_get_fee_time_inconsistency.c index ff1f570e8..f7e4f171d 100644 --- a/src/auditordb/pg_get_fee_time_inconsistency.c +++ b/src/auditordb/pg_get_fee_time_inconsistency.c @@ -13,16 +13,14 @@ You should have 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 "platform.h" #include "taler_error_codes.h" #include "taler_dbevents.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_get_fee_time_inconsistency.h" + /** * Closure for #feetimeinconsistency_cb(). */ @@ -66,22 +64,20 @@ fee_time_inconsistency_cb (void *cls, unsigned int num_results) { struct FeeTimeInconsistencyContext *dcc = cls; - // struct PostgresClosure *pg = dcc->pg; - for (unsigned int i = 0; i < num_results; i++) { - uint64_t serial_id; - struct TALER_AUDITORDB_FeeTimeInconsistency dc; - struct GNUNET_PQ_ResultSpec rs[] = { - - GNUNET_PQ_result_spec_uint64 ("row_id", &serial_id), - - GNUNET_PQ_result_spec_string ("type", &dc.type), - GNUNET_PQ_result_spec_absolute_time ("time", &dc.time), - GNUNET_PQ_result_spec_string ("diagnostic", &dc.diagnostic), - + 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; @@ -95,11 +91,8 @@ fee_time_inconsistency_cb (void *cls, 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) @@ -113,14 +106,12 @@ TAH_PG_get_fee_time_inconsistency ( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, // maybe not needed + bool return_suppressed, TALER_AUDITORDB_FeeTimeInconsistencyCallback cb, void *cb_cls) { - - uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); - struct PostgresClosure *pg = 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), @@ -138,12 +129,13 @@ TAH_PG_get_fee_time_inconsistency ( "auditor_fee_time_inconsistency_get_desc", "SELECT" " row_id" - ",type" - ",time" + ",problem_row_id" + ",fee_type" + ",fee_time" ",diagnostic" " FROM auditor_fee_time_inconsistency" " WHERE (row_id < $1)" - " AND ($2 OR suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id DESC" " LIMIT $3" ); @@ -151,26 +143,26 @@ TAH_PG_get_fee_time_inconsistency ( "auditor_fee_time_inconsistency_get_asc", "SELECT" " row_id" - ",type" - ",time" + ",problem_row_id" + ",fee_type" + ",fee_time" ",diagnostic" " FROM auditor_fee_time_inconsistency" " WHERE (row_id > $1)" - " AND ($2 OR suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id ASC" " LIMIT $3" ); - qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, - (limit > 0) ? - "auditor_fee_time_inconsistency_get_asc" - : - "auditor_fee_time_inconsistency_get_desc", - params, - &fee_time_inconsistency_cb, - &dcc); - + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->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; -}
\ No newline at end of file +} diff --git a/src/auditordb/pg_get_misattribution_in_inconsistency.c b/src/auditordb/pg_get_misattribution_in_inconsistency.c index 1b31d1a4e..d7c12fc9a 100644 --- a/src/auditordb/pg_get_misattribution_in_inconsistency.c +++ b/src/auditordb/pg_get_misattribution_in_inconsistency.c @@ -68,14 +68,18 @@ misattribution_in_inconsistency_cb (void *cls, for (unsigned int i = 0; i < num_results; i++) { - uint64_t serial_id; struct TALER_AUDITORDB_MisattributionInInconsistency dc; struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_uint64 ("row_id", &serial_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_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; @@ -91,7 +95,6 @@ misattribution_in_inconsistency_cb (void *cls, } dcc->qs = i + 1; rval = dcc->cb (dcc->cb_cls, - serial_id, &dc); GNUNET_PQ_cleanup_result (rs); if (GNUNET_OK != rval) @@ -105,14 +108,12 @@ TAH_PG_get_misattribution_in_inconsistency ( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, // maybe not needed + bool return_suppressed, TALER_AUDITORDB_MisattributionInInconsistencyCallback cb, void *cb_cls) { - - uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); - struct PostgresClosure *pg = 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), @@ -129,42 +130,39 @@ TAH_PG_get_misattribution_in_inconsistency ( PREPARE (pg, "auditor_misattribution_in_inconsistency_get_desc", "SELECT" - " row_id," - " amount," - " bank_row," - " reserve_pub," - " suppressed" + " row_id" + ",amount" + ",bank_row" + ",reserve_pub" + ",suppressed" " FROM auditor_misattribution_in_inconsistency" " WHERE (row_id < $1)" - " AND ($2 OR suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id DESC" " LIMIT $3" ); PREPARE (pg, "auditor_misattribution_in_inconsistency_get_asc", "SELECT" - " row_id," - " amount," - " bank_row," - " reserve_pub," - " suppressed" + " row_id" + ",amount" + ",bank_row" + ",reserve_pub" + ",suppressed" " FROM auditor_misattribution_in_inconsistency" " WHERE (row_id > $1)" - " AND ($2 OR suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id ASC" " LIMIT $3" ); - qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, - (limit > 0) - ? - "auditor_misattribution_in_inconsistency_get_asc" - : - "auditor_misattribution_in_inconsistency_get_desc", - params, - &misattribution_in_inconsistency_cb - , - &dcc); - + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->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); diff --git a/src/auditordb/pg_get_progress_points.c b/src/auditordb/pg_get_progress_points.c new file mode 100644 index 000000000..12c585235 --- /dev/null +++ b/src/auditordb/pg_get_progress_points.c @@ -0,0 +1,140 @@ +/* + 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 auditordb/pg_get_progress_points.c + * @brief Implementation of the get_progress_points function for Postgres + * @author Christian Grothoff + */ +#include "platform.h" +#include "taler_error_codes.h" +#include "taler_dbevents.h" +#include "taler_pq_lib.h" +#include "pg_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 PostgresClosure *pg; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #TAH_PG_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 (void *cls, + 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 +TAH_PG_get_progress_points ( + void *cls, + const char *progress_key, + TALER_AUDITORDB_ProgressPointsCallback cb, + void *cb_cls) +{ + struct PostgresClosure *pg = 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, + .pg = pg + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (pg, + "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 ( + pg->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/pg_delete_deposit_confirmations.h b/src/auditordb/pg_get_progress_points.h index 5f7700ba1..c044d3e2f 100644 --- a/src/auditordb/pg_delete_deposit_confirmations.h +++ b/src/auditordb/pg_get_progress_points.h @@ -14,28 +14,33 @@ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ /** - * @file auditordb/pg_delete_deposit_confirmations.h - * @brief implementation of the delete_deposit_confirmation function for Postgres - * @author Nicola Eigel + * @file auditordb/pg_get_progress_points.h + * @brief implementation of the get_progress_points function for Postgres + * @author Christian Grothoff */ -#ifndef PG_DELETE_DEPOSIT_CONFIRMATIONS_H -#define PG_DELETE_DEPOSIT_CONFIRMATIONS_H +#ifndef PG_GET_PROGRESS_POINTS_H +#define PG_GET_PROGRESS_POINTS_H #include "taler_util.h" #include "taler_json_lib.h" #include "taler_auditordb_plugin.h" + /** - * Delete a row from the deposit confirmations table. + * Get information about progress from the database. * * @param cls the @e cls of this struct with the plugin-specific state - * @param row_id row to delete - * @return query transaction status + * @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 -TAH_PG_delete_deposit_confirmation ( +TAH_PG_get_progress_points ( void *cls, - uint64_t row_id); + const char *progress_key, + TALER_AUDITORDB_ProgressPointsCallback cb, + void *cb_cls); #endif diff --git a/src/auditordb/pg_get_purse_not_closed_inconsistencies.c b/src/auditordb/pg_get_purse_not_closed_inconsistencies.c index c764292fe..34be2f6f7 100644 --- a/src/auditordb/pg_get_purse_not_closed_inconsistencies.c +++ b/src/auditordb/pg_get_purse_not_closed_inconsistencies.c @@ -13,15 +13,11 @@ You should have 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 "platform.h" #include "taler_error_codes.h" #include "taler_dbevents.h" #include "taler_pq_lib.h" #include "pg_helper.h" - - #include "pg_get_purse_not_closed_inconsistencies.h" @@ -72,18 +68,18 @@ purse_not_closed_inconsistencies_cb (void *cls, for (unsigned int i = 0; i < num_results; i++) { - uint64_t serial_id; - struct TALER_AUDITORDB_PurseNotClosedInconsistencies dc; - struct GNUNET_PQ_ResultSpec rs[] = { - - GNUNET_PQ_result_spec_uint64 ("row_id", &serial_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_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; @@ -97,11 +93,8 @@ purse_not_closed_inconsistencies_cb (void *cls, 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) @@ -115,14 +108,12 @@ TAH_PG_get_purse_not_closed_inconsistencies ( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, // maybe not needed + bool return_suppressed, TALER_AUDITORDB_PurseNotClosedInconsistenciesCallback cb, void *cb_cls) { - - uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); - struct PostgresClosure *pg = 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), @@ -143,9 +134,10 @@ TAH_PG_get_purse_not_closed_inconsistencies ( ",purse_pub" ",amount" ",expiration_date" + ",suppressed" " FROM auditor_purse_not_closed_inconsistencies" " WHERE (row_id < $1)" - " AND ($2 OR suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id DESC" " LIMIT $3" ); @@ -156,22 +148,21 @@ TAH_PG_get_purse_not_closed_inconsistencies ( ",purse_pub" ",amount" ",expiration_date" + ",suppressed" " FROM auditor_purse_not_closed_inconsistencies" " WHERE (row_id > $1)" - " AND ($2 OR suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id ASC" " LIMIT $3" ); - qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, - (limit > 0) ? - "auditor_purse_not_closed_inconsistencies_get_asc" - : - "auditor_purse_not_closed_inconsistencies_get_desc", - params, - & - purse_not_closed_inconsistencies_cb, - &dcc); - + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->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); diff --git a/src/auditordb/pg_get_purses.c b/src/auditordb/pg_get_purses.c index b415d9aad..922e5c2a1 100644 --- a/src/auditordb/pg_get_purses.c +++ b/src/auditordb/pg_get_purses.c @@ -106,12 +106,11 @@ TAH_PG_get_purses ( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, // maybe not needed TALER_AUDITORDB_PursesCallback cb, void *cb_cls) { - uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); struct PostgresClosure *pg = 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), @@ -133,9 +132,9 @@ TAH_PG_get_purses ( " target," " expiration_date" " FROM auditor_purses" - " WHERE (row_id < $1)" - " ORDER BY row_id DESC" - " LIMIT $3" + " WHERE (auditor_purses_rowid < $1)" + " ORDER BY auditor_purses_rowid DESC" + " LIMIT $2" ); PREPARE (pg, "auditor_purses_get_asc", @@ -146,17 +145,18 @@ TAH_PG_get_purses ( " target," " expiration_date" " FROM auditor_purses" - " WHERE (row_id > $1)" - " ORDER BY row_id ASC" - " LIMIT $3" + " WHERE (auditor_purses_rowid > $1)" + " ORDER BY auditor_purses_rowid ASC" + " LIMIT $2" ); - qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, - (limit > 0) - ? "auditor_purses_get_asc" - : "auditor_purses_get_desc", - params, - &purses_cb, - &dcc); + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->conn, + (limit > 0) + ? "auditor_purses_get_asc" + : "auditor_purses_get_desc", + params, + &purses_cb, + &dcc); if (qs > 0) return dcc.qs; diff --git a/src/auditordb/pg_get_purses.h b/src/auditordb/pg_get_purses.h index 5ee19bf2e..6f6d6659c 100644 --- a/src/auditordb/pg_get_purses.h +++ b/src/auditordb/pg_get_purses.h @@ -13,10 +13,8 @@ You should have 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 SRC_PG_GET_PURSES_H -#define SRC_PG_GET_PURSES_H +#ifndef PG_GET_PURSES_H +#define PG_GET_PURSES_H #include "taler_util.h" #include "taler_json_lib.h" @@ -28,7 +26,6 @@ * @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 @@ -38,7 +35,6 @@ TAH_PG_get_purses ( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, TALER_AUDITORDB_PursesCallback cb, void *cb_cls); diff --git a/src/auditordb/pg_get_refreshes_hanging.c b/src/auditordb/pg_get_refreshes_hanging.c index 353ac5e1e..73c510114 100644 --- a/src/auditordb/pg_get_refreshes_hanging.c +++ b/src/auditordb/pg_get_refreshes_hanging.c @@ -13,17 +13,14 @@ You should have 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 "platform.h" #include "taler_error_codes.h" #include "taler_dbevents.h" #include "taler_pq_lib.h" #include "pg_helper.h" - - #include "pg_get_refreshes_hanging.h" + /** * Closure for #refreshes_hanging_cb(). */ @@ -71,16 +68,14 @@ refreshes_hanging_cb (void *cls, for (unsigned int i = 0; i < num_results; i++) { - uint64_t serial_id; - struct TALER_AUDITORDB_RefreshesHanging dc; - struct GNUNET_PQ_ResultSpec rs[] = { - - GNUNET_PQ_result_spec_uint64 ("row_id", &serial_id), - TALER_PQ_RESULT_SPEC_AMOUNT ("amount", &dc.amount), - GNUNET_PQ_result_spec_auto_from_type ("coin_pub", &dc.coin_pub), - + 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_end }; enum GNUNET_GenericReturnValue rval; @@ -94,11 +89,8 @@ refreshes_hanging_cb (void *cls, 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) @@ -112,14 +104,12 @@ TAH_PG_get_refreshes_hanging ( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, // maybe not needed + bool return_suppressed, TALER_AUDITORDB_RefreshesHangingCallback cb, void *cb_cls) { - - uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); - struct PostgresClosure *pg = 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), @@ -137,8 +127,8 @@ TAH_PG_get_refreshes_hanging ( "auditor_refreshes_hanging_get_desc", "SELECT" " row_id" + ",problem_row_id" ",amount" - ",coin_pub" " FROM auditor_refreshes_hanging" " WHERE (row_id < $1)" " AND ($2 OR suppressed is false)" @@ -149,24 +139,24 @@ TAH_PG_get_refreshes_hanging ( "auditor_refreshes_hanging_get_asc", "SELECT" " row_id" + ",problem_row_id" ",amount" - ",coin_pub" " FROM auditor_refreshes_hanging" " WHERE (row_id > $1)" " AND ($2 OR suppressed is false)" " ORDER BY row_id ASC" " LIMIT $3" ); - qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, - (limit > 0) ? - "auditor_refreshes_hanging_get_asc" - : "auditor_refreshes_hanging_get_desc", - params, - &refreshes_hanging_cb, - &dcc); - + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->conn, + (limit > 0) + ? "auditor_refreshes_hanging_get_asc" + : "auditor_refreshes_hanging_get_desc", + params, + &refreshes_hanging_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/pg_get_reserve_balance_insufficient_inconsistency.c b/src/auditordb/pg_get_reserve_balance_insufficient_inconsistency.c index 97f2f523b..65bbe964e 100644 --- a/src/auditordb/pg_get_reserve_balance_insufficient_inconsistency.c +++ b/src/auditordb/pg_get_reserve_balance_insufficient_inconsistency.c @@ -13,16 +13,14 @@ You should have 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 "platform.h" #include "taler_error_codes.h" #include "taler_dbevents.h" #include "taler_pq_lib.h" #include "pg_helper.h" - - #include "pg_get_reserve_balance_insufficient_inconsistency.h" + /** * Closure for #reserve_balance_insufficient_inconsistency_cb(). */ @@ -70,18 +68,18 @@ reserve_balance_insufficient_inconsistency_cb (void *cls, for (unsigned int i = 0; i < num_results; i++) { - uint64_t serial_id; - struct TALER_AUDITORDB_ReserveBalanceInsufficientInconsistency dc; - struct GNUNET_PQ_ResultSpec rs[] = { - - GNUNET_PQ_result_spec_uint64 ("row_id", &serial_id), - GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", &dc.reserve_pub), - GNUNET_PQ_result_spec_bool ("inconsistency_gain", &dc.inconsistency_gain), + 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; @@ -95,11 +93,8 @@ reserve_balance_insufficient_inconsistency_cb (void *cls, 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) @@ -113,14 +108,12 @@ TAH_PG_get_reserve_balance_insufficient_inconsistency ( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, // maybe not needed + bool return_suppressed, TALER_AUDITORDB_ReserveBalanceInsufficientInconsistencyCallback cb, void *cb_cls) { - - uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); - struct PostgresClosure *pg = 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), @@ -141,9 +134,10 @@ TAH_PG_get_reserve_balance_insufficient_inconsistency ( ",reserve_pub" ",inconsistency_gain" ",inconsistency_amount" + ",suppressed" " FROM auditor_reserve_balance_insufficient_inconsistency" " WHERE (row_id < $1)" - " AND ($2 OR suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id DESC" " LIMIT $3" ); @@ -154,22 +148,21 @@ TAH_PG_get_reserve_balance_insufficient_inconsistency ( ",reserve_pub" ",inconsistency_gain" ",inconsistency_amount" + ",suppressed" " FROM auditor_reserve_balance_insufficient_inconsistency" " WHERE (row_id > $1)" - " AND ($2 OR suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id ASC" " LIMIT $3" ); - qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, - (limit > 0) ? - "auditor_reserve_balance_insufficient_inconsistency_get_asc" - : - "auditor_reserve_balance_insufficient_inconsistency_get_desc", - params, - & - reserve_balance_insufficient_inconsistency_cb, - &dcc); - + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->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); diff --git a/src/auditordb/pg_get_reserve_balance_summary_wrong_inconsistency.c b/src/auditordb/pg_get_reserve_balance_summary_wrong_inconsistency.c index d41d1cbf9..89ef0d178 100644 --- a/src/auditordb/pg_get_reserve_balance_summary_wrong_inconsistency.c +++ b/src/auditordb/pg_get_reserve_balance_summary_wrong_inconsistency.c @@ -13,14 +13,11 @@ You should have 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 "platform.h" #include "taler_error_codes.h" #include "taler_dbevents.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_get_reserve_balance_summary_wrong_inconsistency.h" @@ -65,26 +62,21 @@ reserve_balance_summary_wrong_inconsistency_cb (void *cls, { struct ReserveBalanceSummaryWrongInconsistencyContext *dcc = cls; struct PostgresClosure *pg = dcc->pg; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "---found rbswi's in reserveblanace...\n"); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "---num_results: %u\n", num_results); - for (unsigned int i = 0; i < num_results; i++) { - uint64_t serial_id; - struct TALER_AUDITORDB_ReserveBalanceSummaryWrongInconsistency dc; - struct GNUNET_PQ_ResultSpec rs[] = { - - GNUNET_PQ_result_spec_uint64 ("row_id", &serial_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_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; @@ -98,11 +90,8 @@ reserve_balance_summary_wrong_inconsistency_cb (void *cls, 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) @@ -116,14 +105,12 @@ TAH_PG_get_reserve_balance_summary_wrong_inconsistency ( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, // maybe not needed + bool return_suppressed, TALER_AUDITORDB_ReserveBalanceSummaryWrongInconsistencyCallback cb, void *cb_cls) { - - uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); - struct PostgresClosure *pg = 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), @@ -140,41 +127,39 @@ TAH_PG_get_reserve_balance_summary_wrong_inconsistency ( PREPARE (pg, "auditor_reserve_balance_summary_wrong_inconsistency_get_desc", "SELECT" - " row_id," - " reserve_pub," - " exchange_amount," - " auditor_amount," - " suppressed" + " row_id" + ",reserve_pub" + ",exchange_amount" + ",auditor_amount" + ",suppressed" " FROM auditor_reserve_balance_summary_wrong_inconsistency" " WHERE (row_id < $1)" - " AND ($2 OR suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id DESC" " LIMIT $3" ); PREPARE (pg, "auditor_reserve_balance_summary_wrong_inconsistency_get_asc", "SELECT" - " row_id," - " reserve_pub," - " exchange_amount," - " auditor_amount," - " suppressed" + " row_id" + ",reserve_pub" + ",exchange_amount" + ",auditor_amount" + ",suppressed" " FROM auditor_reserve_balance_summary_wrong_inconsistency" " WHERE (row_id > $1)" - " AND ($2 OR suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id ASC" " LIMIT $3" ); - qs = GNUNET_PQ_eval_prepared_multi_select (pg->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); + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->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; diff --git a/src/auditordb/pg_get_reserve_in_inconsistency.c b/src/auditordb/pg_get_reserve_in_inconsistency.c index 017566f96..b3abc8799 100644 --- a/src/auditordb/pg_get_reserve_in_inconsistency.c +++ b/src/auditordb/pg_get_reserve_in_inconsistency.c @@ -13,14 +13,11 @@ You should have 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 "platform.h" #include "taler_error_codes.h" #include "taler_dbevents.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_get_reserve_in_inconsistency.h" @@ -69,23 +66,26 @@ reserve_in_inconsistency_cb (void *cls, for (unsigned int i = 0; i < num_results; i++) { uint64_t serial_id; - struct TALER_AUDITORDB_ReserveInInconsistency dc; - struct GNUNET_PQ_ResultSpec rs[] = { - - GNUNET_PQ_result_spec_uint64 ("row_id", &serial_id), - + GNUNET_PQ_result_spec_uint64 ("row_id", + &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_auto_from_type ("account", &dc.account), - GNUNET_PQ_result_spec_auto_from_type ("diagnostic", &dc.diagnostic), - GNUNET_PQ_result_spec_bool ("suppressed", &dc.suppressed), - - + 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), + 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; @@ -117,14 +117,12 @@ TAH_PG_get_reserve_in_inconsistency ( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, // maybe not needed + bool return_suppressed, TALER_AUDITORDB_ReserveInInconsistencyCallback cb, void *cb_cls) { - - uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); - struct PostgresClosure *pg = 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), @@ -141,14 +139,15 @@ TAH_PG_get_reserve_in_inconsistency ( PREPARE (pg, "auditor_reserve_in_inconsistency_get_desc", "SELECT" - " row_id," - " amount_exchange_expected," - " amount_wired," - " reserve_pub," - " timestamp," - " account," - " diagnostic," - " suppressed" + " 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)" @@ -158,30 +157,29 @@ TAH_PG_get_reserve_in_inconsistency ( PREPARE (pg, "auditor_reserve_in_inconsistency_get_asc", "SELECT" - " row_id," - " amount_exchange_expected," - " amount_wired," - " reserve_pub," - " timestamp," - " account," - " diagnostic," - " suppressed" + " 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 (pg->conn, - (limit > 0) - ? - "auditor_reserve_in_inconsistency_get_asc" - : - "auditor_reserve_in_inconsistency_get_desc", - params, - &reserve_in_inconsistency_cb, - &dcc); - + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->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); diff --git a/src/auditordb/pg_get_reserve_not_closed_inconsistency.c b/src/auditordb/pg_get_reserve_not_closed_inconsistency.c index e5583509e..fbad92a65 100644 --- a/src/auditordb/pg_get_reserve_not_closed_inconsistency.c +++ b/src/auditordb/pg_get_reserve_not_closed_inconsistency.c @@ -13,14 +13,11 @@ You should have 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 "platform.h" #include "taler_error_codes.h" #include "taler_dbevents.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_get_reserve_not_closed_inconsistency.h" @@ -68,22 +65,20 @@ reserve_not_closed_inconsistency_cb (void *cls, for (unsigned int i = 0; i < num_results; i++) { - uint64_t serial_id; - struct TALER_AUDITORDB_ReserveNotClosedInconsistency dc; - struct GNUNET_PQ_ResultSpec rs[] = { - - GNUNET_PQ_result_spec_uint64 ("row_id", &serial_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_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_auto_from_type ("diagnostic", &dc.diagnostic), - GNUNET_PQ_result_spec_bool ("suppressed", &dc.suppressed), - - + 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; @@ -97,11 +92,8 @@ reserve_not_closed_inconsistency_cb (void *cls, 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) @@ -115,14 +107,12 @@ TAH_PG_get_reserve_not_closed_inconsistency ( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, // maybe not needed + bool return_suppressed, TALER_AUDITORDB_ReserveNotClosedInconsistencyCallback cb, void *cb_cls) { - - uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); - struct PostgresClosure *pg = 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), @@ -139,12 +129,12 @@ TAH_PG_get_reserve_not_closed_inconsistency ( PREPARE (pg, "auditor_reserve_not_closed_inconsistency_get_desc", "SELECT" - " row_id," - " reserve_pub," - " balance," - " expiration_time," - " diagnostic," - " suppressed" + " 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)" @@ -154,29 +144,26 @@ TAH_PG_get_reserve_not_closed_inconsistency ( PREPARE (pg, "auditor_reserve_not_closed_inconsistency_get_asc", "SELECT" - " row_id," - " reserve_pub," - " balance," - " expiration_time," - " diagnostic," - " suppressed" + " 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 (pg->conn, - (limit > 0) - ? - "auditor_reserve_not_closed_inconsistency_get_asc" - : - "auditor_reserve_not_closed_inconsistency_get_desc", - params, - & - reserve_not_closed_inconsistency_cb, - &dcc); - + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->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); diff --git a/src/auditordb/pg_get_reserves.c b/src/auditordb/pg_get_reserves.c index 32247c4ec..222fec908 100644 --- a/src/auditordb/pg_get_reserves.c +++ b/src/auditordb/pg_get_reserves.c @@ -69,19 +69,26 @@ reserves_cb (void *cls, 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), + 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 ("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), + GNUNET_PQ_result_spec_string ("origin_account", + &dc.origin_account), GNUNET_PQ_result_spec_end }; enum GNUNET_GenericReturnValue rval; @@ -111,7 +118,6 @@ TAH_PG_get_reserves ( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, // maybe not needed TALER_AUDITORDB_ReservesCallback cb, void *cb_cls) { @@ -145,8 +151,8 @@ TAH_PG_get_reserves ( " origin_account" " FROM auditor_reserves" " WHERE (auditor_reserves_rowid < $1)" - " ORDER BY row_id DESC" - " LIMIT $3" + " ORDER BY auditor_reserves_rowid DESC" + " LIMIT $2" ); PREPARE (pg, "auditor_reserves_get_asc", @@ -164,16 +170,17 @@ TAH_PG_get_reserves ( " origin_account" " FROM auditor_reserves" " WHERE (auditor_reserves_rowid > $1)" - " ORDER BY row_id ASC" - " LIMIT $3" + " ORDER BY auditor_reserves_rowid ASC" + " LIMIT $2" ); - qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, - (limit > 0) - ? "auditor_reserves_get_asc" - : "auditor_reserves_get_desc", - params, - &reserves_cb, - &dcc); + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->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); diff --git a/src/auditordb/pg_get_reserves.h b/src/auditordb/pg_get_reserves.h index 6c07233b3..f6fe0776e 100644 --- a/src/auditordb/pg_get_reserves.h +++ b/src/auditordb/pg_get_reserves.h @@ -13,10 +13,8 @@ You should have 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 SRC_PG_GET_RESERVES_H -#define SRC_PG_GET_RESERVES_H +#ifndef PG_GET_RESERVES_H +#define PG_GET_RESERVES_H #include "taler_util.h" #include "taler_json_lib.h" @@ -28,7 +26,6 @@ * @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 @@ -38,7 +35,6 @@ TAH_PG_get_reserves ( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, TALER_AUDITORDB_ReservesCallback cb, void *cb_cls); diff --git a/src/auditordb/pg_get_row_minor_inconsistencies.c b/src/auditordb/pg_get_row_minor_inconsistencies.c index c6a15b155..cd92dcce6 100644 --- a/src/auditordb/pg_get_row_minor_inconsistencies.c +++ b/src/auditordb/pg_get_row_minor_inconsistencies.c @@ -13,14 +13,11 @@ You should have 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 "platform.h" #include "taler_error_codes.h" #include "taler_dbevents.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_get_row_minor_inconsistencies.h" @@ -64,23 +61,21 @@ row_minor_inconsistencies_cb (void *cls, unsigned int num_results) { struct RowMinorInconsistenciesContext *dcc = cls; - // struct PostgresClosure *pg = dcc->pg; for (unsigned int i = 0; i < num_results; i++) { - uint64_t serial_id; - struct TALER_AUDITORDB_RowMinorInconsistencies dc; - struct GNUNET_PQ_ResultSpec rs[] = { - - GNUNET_PQ_result_spec_uint64 ("row_id", &serial_id), - - GNUNET_PQ_result_spec_auto_from_type ("row_table", &dc.row_table), - GNUNET_PQ_result_spec_auto_from_type ("diagnostic", &dc.diagnostic), - GNUNET_PQ_result_spec_bool ("suppressed", &dc.suppressed), - - + 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; @@ -94,11 +89,8 @@ row_minor_inconsistencies_cb (void *cls, 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) @@ -112,14 +104,12 @@ TAH_PG_get_row_minor_inconsistencies ( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, // maybe not needed + bool return_suppressed, TALER_AUDITORDB_RowMinorInconsistenciesCallback cb, void *cb_cls) { - - uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); - struct PostgresClosure *pg = 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), @@ -136,39 +126,39 @@ TAH_PG_get_row_minor_inconsistencies ( PREPARE (pg, "auditor_row_minor_inconsistencies_get_desc", "SELECT" - " row_id," - " row_table," - " diagnostic," - " suppressed" + " row_id" + ",problem_row" + ",row_table" + ",diagnostic" + ",suppressed" " FROM auditor_row_minor_inconsistencies" " WHERE (row_id < $1)" - " AND ($2 OR suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id DESC" " LIMIT $3" ); PREPARE (pg, "auditor_row_minor_inconsistencies_get_asc", "SELECT" - " row_id," - " row_table," - " diagnostic," - " suppressed" + " row_id" + ",problem_row" + ",row_table" + ",diagnostic" + ",suppressed" " FROM auditor_row_minor_inconsistencies" " WHERE (row_id > $1)" - " AND ($2 OR suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id ASC" " LIMIT $3" ); - qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, - (limit > 0) - ? - "auditor_row_minor_inconsistencies_get_asc" - : - "auditor_row_minor_inconsistencies_get_desc", - params, - &row_minor_inconsistencies_cb, - &dcc); - + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->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); diff --git a/src/auditordb/pg_get_wire_format_inconsistency.c b/src/auditordb/pg_get_wire_format_inconsistency.c index d94c851c8..d3f2b8960 100644 --- a/src/auditordb/pg_get_wire_format_inconsistency.c +++ b/src/auditordb/pg_get_wire_format_inconsistency.c @@ -13,14 +13,11 @@ You should have 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 "platform.h" #include "taler_error_codes.h" #include "taler_dbevents.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_get_wire_format_inconsistency.h" @@ -68,20 +65,18 @@ wire_format_inconsistency_cb (void *cls, for (unsigned int i = 0; i < num_results; i++) { - uint64_t serial_id; - struct TALER_AUDITORDB_WireFormatInconsistency dc; - struct GNUNET_PQ_ResultSpec rs[] = { - - GNUNET_PQ_result_spec_uint64 ("row_id", &serial_id), - - TALER_PQ_RESULT_SPEC_AMOUNT ("amount", &dc.amount), - GNUNET_PQ_result_spec_int64 ("wire_offset", &dc.wire_offset), - GNUNET_PQ_result_spec_auto_from_type ("diagnostic", &dc.diagnostic), - GNUNET_PQ_result_spec_bool ("suppressed", &dc.suppressed), - - + 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; @@ -95,11 +90,8 @@ wire_format_inconsistency_cb (void *cls, 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) @@ -113,14 +105,12 @@ TAH_PG_get_wire_format_inconsistency ( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, // maybe not needed + bool return_suppressed, TALER_AUDITORDB_WireFormatInconsistencyCallback cb, void *cb_cls) { - - uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); - struct PostgresClosure *pg = 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), @@ -144,7 +134,7 @@ TAH_PG_get_wire_format_inconsistency ( " suppressed" " FROM auditor_wire_format_inconsistency" " WHERE (row_id < $1)" - " AND ($2 OR suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id DESC" " LIMIT $3" ); @@ -158,20 +148,18 @@ TAH_PG_get_wire_format_inconsistency ( " suppressed" " FROM auditor_wire_format_inconsistency" " WHERE (row_id > $1)" - " AND ($2 OR suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id ASC" " LIMIT $3" ); - qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, - (limit > 0) - ? - "auditor_wire_format_inconsistency_get_asc" - : - "auditor_wire_format_inconsistency_get_desc", - params, - &wire_format_inconsistency_cb, - &dcc); - + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->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); diff --git a/src/auditordb/pg_get_wire_out_inconsistency.c b/src/auditordb/pg_get_wire_out_inconsistency.c index d885a2fa1..4e9ca905f 100644 --- a/src/auditordb/pg_get_wire_out_inconsistency.c +++ b/src/auditordb/pg_get_wire_out_inconsistency.c @@ -13,14 +13,11 @@ You should have 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 "platform.h" #include "taler_error_codes.h" #include "taler_dbevents.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_get_wire_out_inconsistency.h" @@ -68,21 +65,22 @@ wire_out_inconsistency_cb (void *cls, for (unsigned int i = 0; i < num_results; i++) { - uint64_t serial_id; - struct TALER_AUDITORDB_WireOutInconsistency dc; - struct GNUNET_PQ_ResultSpec rs[] = { - - GNUNET_PQ_result_spec_uint64 ("row_id", &serial_id), - + GNUNET_PQ_result_spec_uint64 ("row_id", + &dc.row_id), GNUNET_PQ_result_spec_string ("destination_account", &dc.destination_account), - 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_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; @@ -96,11 +94,8 @@ wire_out_inconsistency_cb (void *cls, 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) @@ -114,14 +109,12 @@ TAH_PG_get_wire_out_inconsistency ( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, // maybe not needed + bool return_suppressed, TALER_AUDITORDB_WireOutInconsistencyCallback cb, void *cb_cls) { - - uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); - struct PostgresClosure *pg = 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), @@ -138,41 +131,43 @@ TAH_PG_get_wire_out_inconsistency ( PREPARE (pg, "auditor_wire_out_inconsistency_get_desc", "SELECT" - " row_id," - " destination_account," - " expected," - " claimed," - " suppressed" + " row_id" + ",destination_account" + ",diagnostic" + ",wire_out_serial_id" + ",expected" + ",claimed" + ",suppressed" " FROM auditor_wire_out_inconsistency" " WHERE (row_id < $1)" - " AND ($2 OR suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id DESC" " LIMIT $3" ); PREPARE (pg, "auditor_wire_out_inconsistency_get_asc", "SELECT" - " row_id," - " destination_account," - " expected," - " claimed," - " suppressed" + " row_id" + ",destination_account" + ",diagnostic" + ",wire_out_serial_id" + ",expected" + ",claimed" + ",suppressed" " FROM auditor_wire_out_inconsistency" " WHERE (row_id > $1)" - " AND ($2 OR suppressed is false)" + " AND ($2 OR NOT suppressed)" " ORDER BY row_id ASC" " LIMIT $3" ); - qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, - (limit > 0) - ? - "auditor_wire_out_inconsistency_get_asc" - : - "auditor_wire_out_inconsistency_get_desc", - params, - &wire_out_inconsistency_cb, - &dcc); - + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->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); diff --git a/src/auditordb/pg_helper.c b/src/auditordb/pg_helper.c new file mode 100644 index 000000000..a3664aab1 --- /dev/null +++ b/src/auditordb/pg_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 "platform.h" +#include "taler_auditordb_plugin.h" +#include <ltdl.h> +#include "pg_helper.h" + + +const char * +TAH_PG_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/pg_helper.h b/src/auditordb/pg_helper.h index 3c22dd424..f2c17f01c 100644 --- a/src/auditordb/pg_helper.h +++ b/src/auditordb/pg_helper.h @@ -27,7 +27,7 @@ // FIXME: comment const char * -TAH_PG_get_table_name (enum TALER_AUDITORDB_SuppressableTables table); +TAH_PG_get_deletable_suppressable_table_name (enum TALER_AUDITORDB_DeletableSuppressableTables table); /** @@ -75,27 +75,27 @@ struct PostgresClosure * @param name name to prepare the statement under * @param sql actual SQL text */ -#define PREPARE(pg,name,sql) \ +#define PREPARE(pg,name,sql) \ do { \ static struct { \ unsigned long long cnt; \ struct PostgresClosure *pg; \ - } preps[2]; /* 2 ctrs for taler-auditor-sync*/ \ - unsigned int off = 0; \ - \ - while ( (NULL != preps[off].pg) && \ - (pg != preps[off].pg) && \ - (off < sizeof(preps) / sizeof(*preps)) ) \ - off++; \ - GNUNET_assert (off < \ - sizeof(preps) / sizeof(*preps)); \ - if (preps[off].cnt < pg->prep_gen) \ + } preps_[2]; /* 2 ctrs for taler-auditor-sync*/ \ + unsigned int off_ = 0; \ + \ + while ( (NULL != preps_[off_].pg) && \ + (pg != preps_[off_].pg) && \ + (off_ < sizeof(preps_) / sizeof(*preps_)) ) \ + off_++; \ + GNUNET_assert (off_ < \ + sizeof(preps_) / sizeof(*preps_)); \ + if (preps_[off_].cnt < pg->prep_gen) \ { \ struct GNUNET_PQ_PreparedStatement ps[] = { \ GNUNET_PQ_make_prepare (name, sql), \ GNUNET_PQ_PREPARED_STATEMENT_END \ }; \ - \ + \ if (GNUNET_OK != \ GNUNET_PQ_prepare_statements (pg->conn, \ ps)) \ @@ -103,8 +103,8 @@ struct PostgresClosure GNUNET_break (0); \ return GNUNET_DB_STATUS_HARD_ERROR; \ } \ - preps[off].pg = pg; \ - preps[off].cnt = pg->prep_gen; \ + preps_[off_].pg = pg; \ + preps_[off_].cnt = pg->prep_gen; \ } \ } while (0) diff --git a/src/auditordb/pg_insert_amount_arithmetic_inconsistency.c b/src/auditordb/pg_insert_amount_arithmetic_inconsistency.c index afc84e5ba..4a58c5985 100644 --- a/src/auditordb/pg_insert_amount_arithmetic_inconsistency.c +++ b/src/auditordb/pg_insert_amount_arithmetic_inconsistency.c @@ -13,12 +13,9 @@ You should have 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 "platform.h" #include "taler_pq_lib.h" - #include "pg_helper.h" - #include "pg_insert_amount_arithmetic_inconsistency.h" enum GNUNET_DB_QueryStatus @@ -28,12 +25,13 @@ TAH_PG_insert_amount_arithmetic_inconsistency ( { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_string (dc->operation), - TALER_PQ_query_param_amount (pg->conn, &dc->exchange_amount), - TALER_PQ_query_param_amount (pg->conn, &dc->auditor_amount), + GNUNET_PQ_query_param_uint64 (&dc->problem_row_id), + TALER_PQ_query_param_amount (pg->conn, + &dc->exchange_amount), + TALER_PQ_query_param_amount (pg->conn, + &dc->auditor_amount), GNUNET_PQ_query_param_bool (dc->profitable), - GNUNET_PQ_query_param_end }; @@ -41,15 +39,11 @@ TAH_PG_insert_amount_arithmetic_inconsistency ( "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)" - " ON CONFLICT (operation) DO UPDATE" - " SET exchange_amount = excluded.exchange_amount," - " auditor_amount = excluded.auditor_amount," - " profitable = excluded.profitable," - " suppressed = false;" + ") VALUES ($1,$2,$3,$4,$5);" ); return GNUNET_PQ_eval_prepared_non_select (pg->conn, "auditor_amount_arithmetic_inconsistency_insert", diff --git a/src/auditordb/pg_insert_auditor_closure_lags.c b/src/auditordb/pg_insert_auditor_closure_lags.c index e858f5ac7..b437a5d7f 100644 --- a/src/auditordb/pg_insert_auditor_closure_lags.c +++ b/src/auditordb/pg_insert_auditor_closure_lags.c @@ -13,14 +13,12 @@ You should have 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 "platform.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_insert_auditor_closure_lags.h" + enum GNUNET_DB_QueryStatus TAH_PG_insert_auditor_closure_lags ( void *cls, @@ -28,12 +26,12 @@ TAH_PG_insert_auditor_closure_lags ( { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { - - TALER_PQ_query_param_amount (pg->conn, &dc->amount), + TALER_PQ_query_param_amount (pg->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), - GNUNET_PQ_query_param_end }; @@ -41,10 +39,11 @@ TAH_PG_insert_auditor_closure_lags ( "auditor_closure_lags_insert", "INSERT INTO auditor_closure_lags " "(amount" + ",problem_row_id" ",deadline" ",wtid" ",account" - ") VALUES ($1,$2,$3,$4);"); + ") VALUES ($1,$2,$3,$4,$5);"); return GNUNET_PQ_eval_prepared_non_select (pg->conn, "auditor_closure_lags_insert", params); diff --git a/src/auditordb/pg_insert_bad_sig_losses.c b/src/auditordb/pg_insert_bad_sig_losses.c index 88ce7d2aa..7cf7cf5cc 100644 --- a/src/auditordb/pg_insert_bad_sig_losses.c +++ b/src/auditordb/pg_insert_bad_sig_losses.c @@ -13,14 +13,12 @@ You should have 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 "platform.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_insert_bad_sig_losses.h" + enum GNUNET_DB_QueryStatus TAH_PG_insert_bad_sig_losses ( void *cls, @@ -28,30 +26,22 @@ TAH_PG_insert_bad_sig_losses ( { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_string (dc->operation), - TALER_PQ_query_param_amount (pg->conn, &dc->loss), + GNUNET_PQ_query_param_uint64 (&dc->problem_row_id), + TALER_PQ_query_param_amount (pg->conn, + &dc->loss), GNUNET_PQ_query_param_auto_from_type (&dc->operation_specific_pub), - GNUNET_PQ_query_param_end }; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "--storing new bsl\n"); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "--operation %s\n", dc->operation); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "--loss %s\n", TALER_amount_to_string ( - &dc->loss)); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "--operation_specific_pub %s\n", - TALER_B2S (&dc->operation_specific_pub)); PREPARE (pg, "auditor_bad_sig_losses_insert", "INSERT INTO auditor_bad_sig_losses " "(operation" + ",problem_row_id" ",loss" ",operation_specific_pub" - ") VALUES ($1,$2,$3)" - " ON CONFLICT (operation, operation_specific_pub) DO UPDATE" - " SET loss = excluded.loss," - " suppressed = false;" + ") VALUES ($1,$2,$3,$4);" ); return GNUNET_PQ_eval_prepared_non_select (pg->conn, "auditor_bad_sig_losses_insert", diff --git a/src/auditordb/pg_insert_coin_inconsistency.c b/src/auditordb/pg_insert_coin_inconsistency.c index 32c57a3c8..70d105175 100644 --- a/src/auditordb/pg_insert_coin_inconsistency.c +++ b/src/auditordb/pg_insert_coin_inconsistency.c @@ -13,13 +13,9 @@ You should have 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 "platform.h" #include "taler_pq_lib.h" - #include "pg_helper.h" - #include "pg_insert_coin_inconsistency.h" @@ -30,7 +26,6 @@ TAH_PG_insert_coin_inconsistency ( { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_string (dc->operation), TALER_PQ_query_param_amount (pg->conn, &dc->exchange_amount), @@ -38,7 +33,6 @@ TAH_PG_insert_coin_inconsistency ( &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 }; @@ -46,16 +40,12 @@ TAH_PG_insert_coin_inconsistency ( "auditor_coin_inconsistency_insert", "INSERT INTO auditor_coin_inconsistency " "(operation" + ",problem_row_id" ",exchange_amount" ",auditor_amount" ",coin_pub" ",profitable" - ") VALUES ($1,$2,$3,$4,$5)" - " ON CONFLICT (operation, coin_pub) DO UPDATE" - " SET exchange_amount = excluded.exchange_amount," - " auditor_amount = excluded.auditor_amount," - " profitable = excluded.profitable," - " suppressed = false;" + ") VALUES ($1,$2,$3,$4,$5,$6)" ); return GNUNET_PQ_eval_prepared_non_select (pg->conn, "auditor_coin_inconsistency_insert", diff --git a/src/auditordb/pg_insert_denomination_key_validity_withdraw_inconsistency.c b/src/auditordb/pg_insert_denomination_key_validity_withdraw_inconsistency.c index 2d0cb3cf5..9755739f3 100644 --- a/src/auditordb/pg_insert_denomination_key_validity_withdraw_inconsistency.c +++ b/src/auditordb/pg_insert_denomination_key_validity_withdraw_inconsistency.c @@ -13,14 +13,12 @@ You should have 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 "platform.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_insert_denomination_key_validity_withdraw_inconsistency.h" + enum GNUNET_DB_QueryStatus TAH_PG_insert_denomination_key_validity_withdraw_inconsistency ( void *cls, @@ -28,8 +26,8 @@ TAH_PG_insert_denomination_key_validity_withdraw_inconsistency ( { struct PostgresClosure *pg = cls; 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), @@ -40,9 +38,10 @@ TAH_PG_insert_denomination_key_validity_withdraw_inconsistency ( "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);"); + ") VALUES ($1,$2,$3,$4);"); return GNUNET_PQ_eval_prepared_non_select (pg->conn, "auditor_denomination_key_validity_withdraw_inconsistency_insert", params); diff --git a/src/auditordb/pg_insert_denominations_without_sigs.c b/src/auditordb/pg_insert_denominations_without_sigs.c index f06034602..d8aacbd0b 100644 --- a/src/auditordb/pg_insert_denominations_without_sigs.c +++ b/src/auditordb/pg_insert_denominations_without_sigs.c @@ -13,14 +13,12 @@ You should have 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 "platform.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_insert_denominations_without_sigs.h" + enum GNUNET_DB_QueryStatus TAH_PG_insert_denominations_without_sigs ( void *cls, @@ -28,13 +26,10 @@ TAH_PG_insert_denominations_without_sigs ( { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (&dc->denompub_h), TALER_PQ_query_param_amount (pg->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 }; diff --git a/src/auditordb/pg_insert_emergency.c b/src/auditordb/pg_insert_emergency.c index a966be43b..6af7c527f 100644 --- a/src/auditordb/pg_insert_emergency.c +++ b/src/auditordb/pg_insert_emergency.c @@ -13,14 +13,12 @@ You should have 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 "platform.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_insert_emergency.h" + enum GNUNET_DB_QueryStatus TAH_PG_insert_emergency ( void *cls, @@ -28,14 +26,15 @@ TAH_PG_insert_emergency ( { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (&dc->denompub_h), - TALER_PQ_query_param_amount (pg->conn, &dc->denom_risk), - TALER_PQ_query_param_amount (pg->conn, &dc->denom_loss), + TALER_PQ_query_param_amount (pg->conn, + &dc->denom_risk), + TALER_PQ_query_param_amount (pg->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 (pg->conn,&dc->value), - + TALER_PQ_query_param_amount (pg->conn, + &dc->value), GNUNET_PQ_query_param_end }; diff --git a/src/auditordb/pg_insert_exchange_signkey.c b/src/auditordb/pg_insert_exchange_signkey.c index c31456737..489e01721 100644 --- a/src/auditordb/pg_insert_exchange_signkey.c +++ b/src/auditordb/pg_insert_exchange_signkey.c @@ -44,9 +44,9 @@ TAH_PG_insert_exchange_signkey ( PREPARE (pg, "auditor_insert_exchange_signkey", "INSERT INTO auditor_exchange_signkeys " - "(ep_start" - ",ep_expire" - ",ep_end" + "(ep_valid_from" + ",ep_expire_sign" + ",ep_expire_legal" ",exchange_pub" ",master_sig" ") VALUES ($1,$2,$3,$4,$5);" diff --git a/src/auditordb/pg_insert_fee_time_inconsistency.c b/src/auditordb/pg_insert_fee_time_inconsistency.c index ad1a8b25f..4316ba2c8 100644 --- a/src/auditordb/pg_insert_fee_time_inconsistency.c +++ b/src/auditordb/pg_insert_fee_time_inconsistency.c @@ -13,14 +13,12 @@ You should have 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 "platform.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_insert_fee_time_inconsistency.h" + enum GNUNET_DB_QueryStatus TAH_PG_insert_fee_time_inconsistency ( void *cls, @@ -28,22 +26,21 @@ TAH_PG_insert_fee_time_inconsistency ( { struct PostgresClosure *pg = cls; 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 (pg, "auditor_fee_time_inconsistency_insert", "INSERT INTO auditor_fee_time_inconsistency " - "(type" - ",time" + "(fee_type" + ",problem_row_id" + ",fee_time" ",diagnostic" - ") VALUES ($1,$2,$3);"); + ") VALUES ($1,$2,$3,$4);"); return GNUNET_PQ_eval_prepared_non_select (pg->conn, "auditor_fee_time_inconsistency_insert", params); diff --git a/src/auditordb/pg_insert_misattribution_in_inconsistency.c b/src/auditordb/pg_insert_misattribution_in_inconsistency.c index 1db7d86d6..e1641c61c 100644 --- a/src/auditordb/pg_insert_misattribution_in_inconsistency.c +++ b/src/auditordb/pg_insert_misattribution_in_inconsistency.c @@ -18,6 +18,7 @@ #include "pg_helper.h" #include "pg_insert_misattribution_in_inconsistency.h" + enum GNUNET_DB_QueryStatus TAH_PG_insert_misattribution_in_inconsistency ( void *cls, @@ -25,7 +26,8 @@ TAH_PG_insert_misattribution_in_inconsistency ( { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { - TALER_PQ_query_param_amount (pg->conn, &dc->amount), + TALER_PQ_query_param_amount (pg->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 @@ -34,11 +36,10 @@ TAH_PG_insert_misattribution_in_inconsistency ( PREPARE (pg, "auditor_misattribution_in_inconsistency_insert", "INSERT INTO auditor_misattribution_in_inconsistency " - "(row_id," - " amount," + "(amount," " bank_row," " reserve_pub" - ") VALUES ($1,$2,$3,$4);" + ") VALUES ($1,$2,$3);" ); return GNUNET_PQ_eval_prepared_non_select (pg->conn, "auditor_misattribution_in_inconsistency_insert", diff --git a/src/auditordb/pg_insert_purse_not_closed_inconsistencies.c b/src/auditordb/pg_insert_purse_not_closed_inconsistencies.c index 7ae2dc7d8..ff8100376 100644 --- a/src/auditordb/pg_insert_purse_not_closed_inconsistencies.c +++ b/src/auditordb/pg_insert_purse_not_closed_inconsistencies.c @@ -13,14 +13,12 @@ You should have 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 "platform.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_insert_purse_not_closed_inconsistencies.h" + enum GNUNET_DB_QueryStatus TAH_PG_insert_purse_not_closed_inconsistencies ( void *cls, @@ -28,11 +26,10 @@ TAH_PG_insert_purse_not_closed_inconsistencies ( { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (&dc->purse_pub), - TALER_PQ_query_param_amount (pg->conn, &dc->amount), + TALER_PQ_query_param_amount (pg->conn, + &dc->amount), GNUNET_PQ_query_param_absolute_time (&dc->expiration_date), - GNUNET_PQ_query_param_end }; @@ -43,10 +40,6 @@ TAH_PG_insert_purse_not_closed_inconsistencies ( ",amount" ",expiration_date" ") VALUES ($1,$2,$3)" - " ON CONFLICT (purse_pub) DO UPDATE" - " SET amount = excluded.amount," - " expiration_date = excluded.expiration_date," - " suppressed = false;" ); return GNUNET_PQ_eval_prepared_non_select (pg->conn, "auditor_purse_not_closed_inconsistencies_insert", diff --git a/src/auditordb/pg_insert_refreshes_hanging.c b/src/auditordb/pg_insert_refreshes_hanging.c index 5a7fe018c..59d6af1f2 100644 --- a/src/auditordb/pg_insert_refreshes_hanging.c +++ b/src/auditordb/pg_insert_refreshes_hanging.c @@ -13,14 +13,12 @@ You should have 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 "platform.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_insert_refreshes_hanging.h" + enum GNUNET_DB_QueryStatus TAH_PG_insert_refreshes_hanging ( void *cls, @@ -28,10 +26,9 @@ TAH_PG_insert_refreshes_hanging ( { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { - - TALER_PQ_query_param_amount (pg->conn, &dc->amount), - GNUNET_PQ_query_param_auto_from_type (&dc->coin_pub), - + TALER_PQ_query_param_amount (pg->conn, + &dc->amount), + GNUNET_PQ_query_param_uint64 (&dc->problem_row_id), GNUNET_PQ_query_param_end }; @@ -39,11 +36,8 @@ TAH_PG_insert_refreshes_hanging ( "auditor_refreshes_hanging_insert", "INSERT INTO auditor_refreshes_hanging " "(amount" - ",coin_pub" - ") VALUES ($1,$2)" - " ON CONFLICT (coin_pub) DO UPDATE" - " SET amount = excluded.amount," - " suppressed = false;" + ",problem_row_id" + ") VALUES ($1,$2);" ); return GNUNET_PQ_eval_prepared_non_select (pg->conn, "auditor_refreshes_hanging_insert", diff --git a/src/auditordb/pg_insert_reserve_in_inconsistency.c b/src/auditordb/pg_insert_reserve_in_inconsistency.c index 9c98b7ace..c584a0ff4 100644 --- a/src/auditordb/pg_insert_reserve_in_inconsistency.c +++ b/src/auditordb/pg_insert_reserve_in_inconsistency.c @@ -13,14 +13,12 @@ You should have 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 "platform.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_insert_reserve_in_inconsistency.h" + enum GNUNET_DB_QueryStatus TAH_PG_insert_reserve_in_inconsistency ( void *cls, @@ -28,22 +26,22 @@ TAH_PG_insert_reserve_in_inconsistency ( { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { - - TALER_PQ_query_param_amount (pg->conn, &dc->amount_exchange_expected), - TALER_PQ_query_param_amount (pg->conn, &dc->amount_wired), + GNUNET_PQ_query_param_uint64 (&dc->bank_row_id), + TALER_PQ_query_param_amount (pg->conn, + &dc->amount_exchange_expected), + TALER_PQ_query_param_amount (pg->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_auto_from_type (&dc->account), - GNUNET_PQ_query_param_auto_from_type (&dc->diagnostic), - - + GNUNET_PQ_query_param_string (dc->account), + GNUNET_PQ_query_param_string (dc->diagnostic), GNUNET_PQ_query_param_end }; PREPARE (pg, "auditor_reserve_in_inconsistency_insert", "INSERT INTO auditor_reserve_in_inconsistency " - "( row_id," + "(bank_row_id," " amount_exchange_expected," " amount_wired," " reserve_pub," diff --git a/src/auditordb/pg_insert_reserve_not_closed_inconsistency.c b/src/auditordb/pg_insert_reserve_not_closed_inconsistency.c index 86d1393cb..9fc0e754d 100644 --- a/src/auditordb/pg_insert_reserve_not_closed_inconsistency.c +++ b/src/auditordb/pg_insert_reserve_not_closed_inconsistency.c @@ -13,14 +13,12 @@ You should have 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 "platform.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_insert_reserve_not_closed_inconsistency.h" + enum GNUNET_DB_QueryStatus TAH_PG_insert_reserve_not_closed_inconsistency ( void *cls, @@ -28,20 +26,18 @@ TAH_PG_insert_reserve_not_closed_inconsistency ( { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (&dc->reserve_pub), - TALER_PQ_query_param_amount (pg->conn, &dc->balance), + TALER_PQ_query_param_amount (pg->conn, + &dc->balance), GNUNET_PQ_query_param_absolute_time (&dc->expiration_time), - GNUNET_PQ_query_param_auto_from_type (&dc->diagnostic), - - + GNUNET_PQ_query_param_string (dc->diagnostic), GNUNET_PQ_query_param_end }; PREPARE (pg, "auditor_reserve_not_closed_inconsistency_insert", "INSERT INTO auditor_reserve_not_closed_inconsistency " - "( reserve_pub," + "(reserve_pub," " balance," " expiration_time," " diagnostic" diff --git a/src/auditordb/pg_insert_row_inconsistency.c b/src/auditordb/pg_insert_row_inconsistency.c index 8ab92dbb7..f5cc630f2 100644 --- a/src/auditordb/pg_insert_row_inconsistency.c +++ b/src/auditordb/pg_insert_row_inconsistency.c @@ -19,6 +19,7 @@ #include "pg_helper.h" #include "pg_insert_row_inconsistency.h" + enum GNUNET_DB_QueryStatus TAH_PG_insert_row_inconsistency ( void *cls, diff --git a/src/auditordb/pg_insert_row_minor_inconsistencies.c b/src/auditordb/pg_insert_row_minor_inconsistencies.c index 84607fa3c..775216872 100644 --- a/src/auditordb/pg_insert_row_minor_inconsistencies.c +++ b/src/auditordb/pg_insert_row_minor_inconsistencies.c @@ -13,14 +13,12 @@ You should have 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 "platform.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_insert_row_minor_inconsistencies.h" + enum GNUNET_DB_QueryStatus TAH_PG_insert_row_minor_inconsistencies ( void *cls, @@ -28,20 +26,18 @@ TAH_PG_insert_row_minor_inconsistencies ( { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { - - GNUNET_PQ_query_param_auto_from_type (&dc->row_table), - GNUNET_PQ_query_param_auto_from_type (&dc->diagnostic), - - + 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 (pg, "auditor_row_minor_inconsistencies_insert", "INSERT INTO auditor_row_minor_inconsistencies " - "( row_id," - " row_table," - " diagnostic" + "(row_table" + ",problem_row" + ",diagnostic" ") VALUES ($1,$2,$3);" ); return GNUNET_PQ_eval_prepared_non_select (pg->conn, diff --git a/src/auditordb/pg_insert_wire_format_inconsistency.c b/src/auditordb/pg_insert_wire_format_inconsistency.c index c4b5b16dc..c70f3ab31 100644 --- a/src/auditordb/pg_insert_wire_format_inconsistency.c +++ b/src/auditordb/pg_insert_wire_format_inconsistency.c @@ -13,14 +13,12 @@ You should have 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 "platform.h" #include "taler_pq_lib.h" #include "pg_helper.h" - #include "pg_insert_wire_format_inconsistency.h" + enum GNUNET_DB_QueryStatus TAH_PG_insert_wire_format_inconsistency ( void *cls, @@ -28,23 +26,20 @@ TAH_PG_insert_wire_format_inconsistency ( { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { - - TALER_PQ_query_param_amount (pg->conn, &dc->amount), - GNUNET_PQ_query_param_int64 (&dc->wire_offset), - GNUNET_PQ_query_param_auto_from_type (&dc->diagnostic), - - + TALER_PQ_query_param_amount (pg->conn, + &dc->amount), + GNUNET_PQ_query_param_uint64 (&dc->wire_offset), + GNUNET_PQ_query_param_string (dc->diagnostic), GNUNET_PQ_query_param_end }; PREPARE (pg, "auditor_wire_format_inconsistency_insert", "INSERT INTO auditor_wire_format_inconsistency " - "( row_id," - " amount," - " wire_offset," - " diagnostic" - ") VALUES ($1,$2,$3,$4);" + "(amount" + ",wire_offset" + ",diagnostic" + ") VALUES ($1,$2,$3);" ); return GNUNET_PQ_eval_prepared_non_select (pg->conn, "auditor_wire_format_inconsistency_insert", diff --git a/src/auditordb/pg_insert_wire_out_inconsistency.c b/src/auditordb/pg_insert_wire_out_inconsistency.c index 828aa3293..2e9354644 100644 --- a/src/auditordb/pg_insert_wire_out_inconsistency.c +++ b/src/auditordb/pg_insert_wire_out_inconsistency.c @@ -28,22 +28,25 @@ TAH_PG_insert_wire_out_inconsistency ( { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_string (dc->destination_account), - TALER_PQ_query_param_amount (pg->conn, &dc->expected), - TALER_PQ_query_param_amount (pg->conn, &dc->claimed), - - + GNUNET_PQ_query_param_string (dc->diagnostic), + GNUNET_PQ_query_param_uint64 (&dc->wire_out_row_id), + TALER_PQ_query_param_amount (pg->conn, + &dc->expected), + TALER_PQ_query_param_amount (pg->conn, + &dc->claimed), GNUNET_PQ_query_param_end }; PREPARE (pg, "auditor_wire_out_inconsistency_insert", "INSERT INTO auditor_wire_out_inconsistency " - "( destination_account," - " expected," - " claimed" - ") VALUES ($1,$2,$3);" + "(destination_account" + ",diagnostic" + ",wire_out_serial_id" + ",expected" + ",claimed" + ") VALUES ($1,$2,$3,$4,$5);" ); return GNUNET_PQ_eval_prepared_non_select (pg->conn, "auditor_wire_out_inconsistency_insert", diff --git a/src/auditordb/pg_select_historic_denom_revenue.h b/src/auditordb/pg_select_historic_denom_revenue.h index 621c7d38d..a3574ec61 100644 --- a/src/auditordb/pg_select_historic_denom_revenue.h +++ b/src/auditordb/pg_select_historic_denom_revenue.h @@ -30,6 +30,8 @@ * 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 diff --git a/src/auditordb/pg_select_historic_reserve_revenue.h b/src/auditordb/pg_select_historic_reserve_revenue.h index e9190e35b..dfdd76e73 100644 --- a/src/auditordb/pg_select_historic_reserve_revenue.h +++ b/src/auditordb/pg_select_historic_reserve_revenue.h @@ -29,6 +29,8 @@ * 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 diff --git a/src/auditordb/pg_update_amount_arithmetic_inconsistency.c b/src/auditordb/pg_update_amount_arithmetic_inconsistency.c deleted file mode 100644 index 581d5c4d8..000000000 --- a/src/auditordb/pg_update_amount_arithmetic_inconsistency.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - 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 "platform.h" -#include "taler_pq_lib.h" -#include "pg_helper.h" - -#include "pg_update_amount_arithmetic_inconsistency.h" - - -enum GNUNET_DB_QueryStatus -TAH_PG_update_amount_arithmetic_inconsistency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&gu->row_id), - GNUNET_PQ_query_param_bool (gu->suppressed), - GNUNET_PQ_query_param_end - }; - - - PREPARE (pg, - "update_amount_arithmetic_inconsistency", - "UPDATE auditor_amount_arithmetic_inconsistency SET" - " suppressed=$2" - " WHERE row_id=$1"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_amount_arithmetic_inconsistency", - params); -} diff --git a/src/auditordb/pg_update_amount_arithmetic_inconsistency.h b/src/auditordb/pg_update_amount_arithmetic_inconsistency.h deleted file mode 100644 index 2ad99ea41..000000000 --- a/src/auditordb/pg_update_amount_arithmetic_inconsistency.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - 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 SRC_PG_UPDATE_AMOUNT_ARITHMETIC_INCONSISTENCY_H -#define SRC_PG_UPDATE_AMOUNT_ARITHMETIC_INCONSISTENCY_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_update_amount_arithmetic_inconsistency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *dc); - -#endif // SRC_PG_UPDATE_AMOUNT_ARITHMETIC_INCONSISTENCY_H diff --git a/src/auditordb/pg_update_bad_sig_losses.c b/src/auditordb/pg_update_bad_sig_losses.c deleted file mode 100644 index 4fdb1ae94..000000000 --- a/src/auditordb/pg_update_bad_sig_losses.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - 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 "platform.h" -#include "taler_pq_lib.h" -#include "pg_helper.h" - -#include "pg_update_bad_sig_losses.h" - - -enum GNUNET_DB_QueryStatus -TAH_PG_update_bad_sig_losses ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&gu->row_id), - GNUNET_PQ_query_param_bool (gu->suppressed), - GNUNET_PQ_query_param_end - }; - - - PREPARE (pg, - "update_bad_sig_losses", - "UPDATE auditor_bad_sig_losses SET" - " suppressed=$2" - " WHERE row_id=$1"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_bad_sig_losses", - params); -} diff --git a/src/auditordb/pg_update_bad_sig_losses.h b/src/auditordb/pg_update_bad_sig_losses.h deleted file mode 100644 index aa36bb847..000000000 --- a/src/auditordb/pg_update_bad_sig_losses.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - 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 SRC_PG_UPDATE_BAD_SIG_LOSSES_H -#define SRC_PG_UPDATE_BAD_SIG_LOSSES_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_update_bad_sig_losses ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *dc); - -#endif // SRC_PG_UPDATE_BAD_SIG_LOSSES_H diff --git a/src/auditordb/pg_update_closure_lags.c b/src/auditordb/pg_update_closure_lags.c deleted file mode 100644 index a49d29f3e..000000000 --- a/src/auditordb/pg_update_closure_lags.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - 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 "platform.h" -#include "taler_pq_lib.h" -#include "pg_helper.h" - -#include "pg_update_closure_lags.h" - -/* -Update a given resource – for now this only means suppressing -*/ -enum GNUNET_DB_QueryStatus -TAH_PG_update_closure_lags ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&gu->row_id), - GNUNET_PQ_query_param_bool (gu->suppressed), - GNUNET_PQ_query_param_end - }; - - - PREPARE (pg, - "update_closure_lags", - "UPDATE auditor_closure_lags SET" - " suppressed=$2" - " WHERE row_id=$1"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_closure_lags", - params); -} diff --git a/src/auditordb/pg_update_closure_lags.h b/src/auditordb/pg_update_closure_lags.h deleted file mode 100644 index 61c9e264a..000000000 --- a/src/auditordb/pg_update_closure_lags.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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 SRC_PG_UPDATE_CLOSURE_LAGS_H -#define SRC_PG_UPDATE_CLOSURE_LAGS_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_update_closure_lags ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *dc); - -#endif // SRC_PG_UPDATE_CLOSURE_LAGS_H diff --git a/src/auditordb/pg_update_coin_inconsistency.c b/src/auditordb/pg_update_coin_inconsistency.c deleted file mode 100644 index e9d845690..000000000 --- a/src/auditordb/pg_update_coin_inconsistency.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - 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 "platform.h" -#include "taler_pq_lib.h" -#include "pg_helper.h" - -#include "pg_update_coin_inconsistency.h" - -/* -Update a given resource – for now this only means suppressing -*/ -enum GNUNET_DB_QueryStatus -TAH_PG_update_coin_inconsistency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&gu->row_id), - GNUNET_PQ_query_param_bool (gu->suppressed), - GNUNET_PQ_query_param_end - }; - - - PREPARE (pg, - "update_coin_inconsistency", - "UPDATE auditor_coin_inconsistency SET" - " suppressed=$2" - " WHERE row_id=$1"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_coin_inconsistency", - params); -} diff --git a/src/auditordb/pg_update_coin_inconsistency.h b/src/auditordb/pg_update_coin_inconsistency.h deleted file mode 100644 index 73c5223e8..000000000 --- a/src/auditordb/pg_update_coin_inconsistency.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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 SRC_PG_UPDATE_COIN_INCONSISTENCY_H -#define SRC_PG_UPDATE_COIN_INCONSISTENCY_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_update_coin_inconsistency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *dc); - -#endif // SRC_PG_UPDATE_COIN_INCONSISTENCY_H diff --git a/src/auditordb/pg_update_denomination_key_validity_withdraw_inconsistency.c b/src/auditordb/pg_update_denomination_key_validity_withdraw_inconsistency.c deleted file mode 100644 index a9b3f820f..000000000 --- a/src/auditordb/pg_update_denomination_key_validity_withdraw_inconsistency.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - 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 "platform.h" -#include "taler_pq_lib.h" -#include "pg_helper.h" - -#include "pg_update_denomination_key_validity_withdraw_inconsistency.h" - -/* -Update a given resource – for now this only means suppressing -*/ -enum GNUNET_DB_QueryStatus -TAH_PG_update_denomination_key_validity_withdraw_inconsistency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&gu->row_id), - GNUNET_PQ_query_param_bool (gu->suppressed), - GNUNET_PQ_query_param_end - }; - - - PREPARE (pg, - "update_denomination_key_validity_withdraw_inconsistency", - "UPDATE auditor_denomination_key_validity_withdraw_inconsistency SET" - " suppressed=$2" - " WHERE row_id=$1"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_denomination_key_validity_withdraw_inconsistency", - params); -} diff --git a/src/auditordb/pg_update_denomination_key_validity_withdraw_inconsistency.h b/src/auditordb/pg_update_denomination_key_validity_withdraw_inconsistency.h deleted file mode 100644 index 574f67b22..000000000 --- a/src/auditordb/pg_update_denomination_key_validity_withdraw_inconsistency.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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 SRC_PG_UPDATE_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_H -#define SRC_PG_UPDATE_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_update_denomination_key_validity_withdraw_inconsistency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *dc); - -#endif // SRC_PG_UPDATE_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_H diff --git a/src/auditordb/pg_update_denomination_pending.c b/src/auditordb/pg_update_denomination_pending.c deleted file mode 100644 index 62129aeaf..000000000 --- a/src/auditordb/pg_update_denomination_pending.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - 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 "platform.h" -#include "taler_pq_lib.h" -#include "pg_helper.h" - -#include "pg_update_denomination_pending.h" - -/* -Update a given resource – for now this only means suppressing -*/ -enum GNUNET_DB_QueryStatus -TAH_PG_update_denomination_pending ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&gu->row_id), - GNUNET_PQ_query_param_bool (gu->suppressed), - GNUNET_PQ_query_param_end - }; - - - PREPARE (pg, - "update_denomination_pending", - "UPDATE auditor_denomination_pending SET" - " suppressed=$2" - " WHERE row_id=$1"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_denomination_pending", - params); -} diff --git a/src/auditordb/pg_update_denomination_pending.h b/src/auditordb/pg_update_denomination_pending.h deleted file mode 100644 index eebed2b0c..000000000 --- a/src/auditordb/pg_update_denomination_pending.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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 SRC_PG_UPDATE_DENOMINATION_PENDING_H -#define SRC_PG_UPDATE_DENOMINATION_PENDING_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_update_denomination_pending ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *dc); - -#endif // SRC_PG_UPDATE_DENOMINATION_PENDING_H diff --git a/src/auditordb/pg_update_denominations_without_sigs.c b/src/auditordb/pg_update_denominations_without_sigs.c deleted file mode 100644 index 39a26a694..000000000 --- a/src/auditordb/pg_update_denominations_without_sigs.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - 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 "platform.h" -#include "taler_pq_lib.h" -#include "pg_helper.h" - -#include "pg_update_denominations_without_sigs.h" - -/* -Update a given resource – for now this only means suppressing -*/ -enum GNUNET_DB_QueryStatus -TAH_PG_update_denominations_without_sigs ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&gu->row_id), - GNUNET_PQ_query_param_bool (gu->suppressed), - GNUNET_PQ_query_param_end - }; - - - PREPARE (pg, - "update_denominations_without_sigs", - "UPDATE auditor_denominations_without_sigs SET" - " suppressed=$2" - " WHERE row_id=$1"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_denominations_without_sigs", - params); -} diff --git a/src/auditordb/pg_update_denominations_without_sigs.h b/src/auditordb/pg_update_denominations_without_sigs.h deleted file mode 100644 index bb126224e..000000000 --- a/src/auditordb/pg_update_denominations_without_sigs.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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 SRC_PG_UPDATE_DENOMINATIONS_WITHOUT_SIGS_H -#define SRC_PG_UPDATE_DENOMINATIONS_WITHOUT_SIGS_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_update_denominations_without_sigs ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *dc); - -#endif // SRC_PG_UPDATE_DENOMINATIONS_WITHOUT_SIGS_H diff --git a/src/auditordb/pg_update_deposit_confirmations.c b/src/auditordb/pg_update_deposit_confirmations.c deleted file mode 100644 index f8774069f..000000000 --- a/src/auditordb/pg_update_deposit_confirmations.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - 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 "platform.h" -#include "taler_pq_lib.h" -#include "pg_helper.h" - -#include "pg_update_deposit_confirmations.h" - -/* -Update a given resource – for now this only means suppressing -*/ -enum GNUNET_DB_QueryStatus -TAH_PG_update_deposit_confirmations ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&gu->row_id), - GNUNET_PQ_query_param_bool (gu->suppressed), - GNUNET_PQ_query_param_end - }; - - - PREPARE (pg, - "update_deposit_confirmations", - "UPDATE auditor_deposit_confirmations SET" - " suppressed=$2" - " WHERE row_id=$1"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_deposit_confirmations", - params); -} diff --git a/src/auditordb/pg_update_deposit_confirmations.h b/src/auditordb/pg_update_deposit_confirmations.h deleted file mode 100644 index 0d2e81d60..000000000 --- a/src/auditordb/pg_update_deposit_confirmations.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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 SRC_PG_UPDATE_DEPOSIT_CONFIRMATIONS_H -#define SRC_PG_UPDATE_DEPOSIT_CONFIRMATIONS_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_update_deposit_confirmations ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *dc); - -#endif // SRC_PG_UPDATE_DEPOSIT_CONFIRMATIONS_H diff --git a/src/auditordb/pg_update_emergency.c b/src/auditordb/pg_update_emergency.c deleted file mode 100644 index 41956675d..000000000 --- a/src/auditordb/pg_update_emergency.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - 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 "platform.h" -#include "taler_pq_lib.h" -#include "pg_helper.h" - -#include "pg_update_emergency.h" - -/* -Update a given resource – for now this only means suppressing -*/ -enum GNUNET_DB_QueryStatus -TAH_PG_update_emergency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&gu->row_id), - GNUNET_PQ_query_param_bool (gu->suppressed), - GNUNET_PQ_query_param_end - }; - - - PREPARE (pg, - "update_emergency", - "UPDATE auditor_emergency SET" - " suppressed=$2" - " WHERE row_id=$1"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_emergency", - params); -} diff --git a/src/auditordb/pg_update_emergency.h b/src/auditordb/pg_update_emergency.h deleted file mode 100644 index 98028dfca..000000000 --- a/src/auditordb/pg_update_emergency.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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 SRC_PG_UPDATE_EMERGENCY_H -#define SRC_PG_UPDATE_EMERGENCY_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_update_emergency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *dc); - -#endif // SRC_PG_UPDATE_EMERGENCY_H diff --git a/src/auditordb/pg_update_emergency_by_count.c b/src/auditordb/pg_update_emergency_by_count.c deleted file mode 100644 index d2c67831c..000000000 --- a/src/auditordb/pg_update_emergency_by_count.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - 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 "platform.h" -#include "taler_pq_lib.h" -#include "pg_helper.h" - -#include "pg_update_emergency_by_count.h" - -/* -Update a given resource – for now this only means suppressing -*/ -enum GNUNET_DB_QueryStatus -TAH_PG_update_emergency_by_count ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&gu->row_id), - GNUNET_PQ_query_param_bool (gu->suppressed), - GNUNET_PQ_query_param_end - }; - - - PREPARE (pg, - "update_emergency_by_count", - "UPDATE auditor_emergency_by_count SET" - " suppressed=$2" - " WHERE row_id=$1"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_emergency_by_count", - params); -} diff --git a/src/auditordb/pg_update_emergency_by_count.h b/src/auditordb/pg_update_emergency_by_count.h deleted file mode 100644 index fa60241d2..000000000 --- a/src/auditordb/pg_update_emergency_by_count.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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 SRC_PG_UPDATE_EMERGENCY_BY_COUNT_H -#define SRC_PG_UPDATE_EMERGENCY_BY_COUNT_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_update_emergency_by_count ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *dc); - -#endif // SRC_PG_UPDATE_EMERGENCY_BY_COUNT_H diff --git a/src/auditordb/pg_update_fee_time_inconsistency.c b/src/auditordb/pg_update_fee_time_inconsistency.c deleted file mode 100644 index fe324edf8..000000000 --- a/src/auditordb/pg_update_fee_time_inconsistency.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - 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 "platform.h" -#include "taler_pq_lib.h" -#include "pg_helper.h" - -#include "pg_update_fee_time_inconsistency.h" - -/* -Update a given resource – for now this only means suppressing -*/ -enum GNUNET_DB_QueryStatus -TAH_PG_update_fee_time_inconsistency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&gu->row_id), - GNUNET_PQ_query_param_bool (gu->suppressed), - GNUNET_PQ_query_param_end - }; - - - PREPARE (pg, - "update_fee_time_inconsistency", - "UPDATE auditor_fee_time_inconsistency SET" - " suppressed=$2" - " WHERE row_id=$1"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_fee_time_inconsistency", - params); -} diff --git a/src/auditordb/pg_update_fee_time_inconsistency.h b/src/auditordb/pg_update_fee_time_inconsistency.h deleted file mode 100644 index ef55de19f..000000000 --- a/src/auditordb/pg_update_fee_time_inconsistency.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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 SRC_PG_UPDATE_FEE_TIME_INCONSISTENCY_H -#define SRC_PG_UPDATE_FEE_TIME_INCONSISTENCY_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_update_fee_time_inconsistency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *dc); - -#endif // SRC_PG_UPDATE_FEE_TIME_INCONSISTENCY_H diff --git a/src/auditordb/pg_update_generic_suppressed.c b/src/auditordb/pg_update_generic_suppressed.c index ef58d855c..e92f27cfd 100644 --- a/src/auditordb/pg_update_generic_suppressed.c +++ b/src/auditordb/pg_update_generic_suppressed.c @@ -13,12 +13,10 @@ You should have 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 "platform.h" #include "taler_pq_lib.h" #include "pg_helper.h" -#include "pg_update_closure_lags.h" +#include "pg_update_generic_suppressed.h" struct Preparations { @@ -38,7 +36,7 @@ struct Preparations enum GNUNET_DB_QueryStatus TAH_PG_update_generic_suppressed ( void *cls, - enum TALER_AUDITORDB_SuppressableTables table, + enum TALER_AUDITORDB_DeletableSuppressableTables table, uint64_t row_id, bool suppressed) { @@ -49,10 +47,10 @@ TAH_PG_update_generic_suppressed ( GNUNET_PQ_query_param_end }; static struct Preparations preps[ - TALER_AUDITORDB_SUPPRESSABLE_TABLES_MAX]; + TALER_AUDITORDB_DELETABLESUPPRESSABLE_TABLES_MAX]; struct Preparations *prep = &preps[table]; - const char *table_name = TAH_PG_get_table_name (table); + const char *table_name = TAH_PG_get_deletable_suppressable_table_name(table); char statement_name[256]; GNUNET_snprintf (statement_name, diff --git a/src/auditordb/pg_update_generic_suppressed.h b/src/auditordb/pg_update_generic_suppressed.h index fffea794a..ab4202891 100644 --- a/src/auditordb/pg_update_generic_suppressed.h +++ b/src/auditordb/pg_update_generic_suppressed.h @@ -33,7 +33,7 @@ enum GNUNET_DB_QueryStatus TAH_PG_update_generic_suppressed ( void *cls, - enum TALER_AUDITORDB_SuppressableTables table, + enum TALER_AUDITORDB_DeletableSuppressableTables table, uint64_t row_id, bool suppressed); diff --git a/src/auditordb/pg_update_misattribution_in_inconsistency.c b/src/auditordb/pg_update_misattribution_in_inconsistency.c deleted file mode 100644 index 5b1b46b04..000000000 --- a/src/auditordb/pg_update_misattribution_in_inconsistency.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - 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 "platform.h" -#include "taler_pq_lib.h" -#include "pg_helper.h" - -#include "pg_update_misattribution_in_inconsistency.h" - -/* -Update a given resource – for now this only means suppressing -*/ -enum GNUNET_DB_QueryStatus -TAH_PG_update_misattribution_in_inconsistency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&gu->row_id), - GNUNET_PQ_query_param_bool (gu->suppressed), - GNUNET_PQ_query_param_end - }; - - - PREPARE (pg, - "update_misattribution_in_inconsistency", - "UPDATE auditor_misattribution_in_inconsistency SET" - " suppressed=$2" - " WHERE row_id=$1"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_misattribution_in_inconsistency", - params); -} diff --git a/src/auditordb/pg_update_misattribution_in_inconsistency.h b/src/auditordb/pg_update_misattribution_in_inconsistency.h deleted file mode 100644 index 840168fcc..000000000 --- a/src/auditordb/pg_update_misattribution_in_inconsistency.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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 SRC_PG_UPDATE_MISATTRIBUTION_IN_INCONSISTENCY_H -#define SRC_PG_UPDATE_MISATTRIBUTION_IN_INCONSISTENCY_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_update_misattribution_in_inconsistency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *dc); - -#endif // SRC_PG_UPDATE_MISATTRIBUTION_IN_INCONSISTENCY_H diff --git a/src/auditordb/pg_update_purse_not_closed_inconsistencies.c b/src/auditordb/pg_update_purse_not_closed_inconsistencies.c deleted file mode 100644 index 97d661d3d..000000000 --- a/src/auditordb/pg_update_purse_not_closed_inconsistencies.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - 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 "platform.h" -#include "taler_pq_lib.h" -#include "pg_helper.h" - -#include "pg_update_purse_not_closed_inconsistencies.h" - -/* -Update a given resource – for now this only means suppressing -*/ -enum GNUNET_DB_QueryStatus -TAH_PG_update_purse_not_closed_inconsistencies ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&gu->row_id), - GNUNET_PQ_query_param_bool (gu->suppressed), - GNUNET_PQ_query_param_end - }; - - - PREPARE (pg, - "update_purse_not_closed_inconsistencies", - "UPDATE auditor_purse_not_closed_inconsistencies SET" - " suppressed=$2" - " WHERE row_id=$1"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_purse_not_closed_inconsistencies", - params); -} diff --git a/src/auditordb/pg_update_purse_not_closed_inconsistencies.h b/src/auditordb/pg_update_purse_not_closed_inconsistencies.h deleted file mode 100644 index 66a677476..000000000 --- a/src/auditordb/pg_update_purse_not_closed_inconsistencies.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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 SRC_PG_UPDATE_PURSE_NOT_CLOSED_INCONSISTENCIES_H -#define SRC_PG_UPDATE_PURSE_NOT_CLOSED_INCONSISTENCIES_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_update_purse_not_closed_inconsistencies ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *dc); - -#endif // SRC_PG_UPDATE_PURSE_NOT_CLOSED_INCONSISTENCIES_H diff --git a/src/auditordb/pg_update_refreshes_hanging.c b/src/auditordb/pg_update_refreshes_hanging.c deleted file mode 100644 index f2dfd0789..000000000 --- a/src/auditordb/pg_update_refreshes_hanging.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - 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 "platform.h" -#include "taler_pq_lib.h" -#include "pg_helper.h" - -#include "pg_update_refreshes_hanging.h" - -/* -Update a given resource – for now this only means suppressing -*/ -enum GNUNET_DB_QueryStatus -TAH_PG_update_refreshes_hanging ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&gu->row_id), - GNUNET_PQ_query_param_bool (gu->suppressed), - GNUNET_PQ_query_param_end - }; - - - PREPARE (pg, - "update_refreshes_hanging", - "UPDATE auditor_refreshes_hanging SET" - " suppressed=$2" - " WHERE row_id=$1"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_refreshes_hanging", - params); -} diff --git a/src/auditordb/pg_update_refreshes_hanging.h b/src/auditordb/pg_update_refreshes_hanging.h deleted file mode 100644 index 071add3cd..000000000 --- a/src/auditordb/pg_update_refreshes_hanging.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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 SRC_PG_UPDATE_REFRESHES_HANGING_H -#define SRC_PG_UPDATE_REFRESHES_HANGING_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_update_refreshes_hanging ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *dc); - -#endif // SRC_PG_UPDATE_REFRESHES_HANGING_H diff --git a/src/auditordb/pg_update_reserve_balance_insufficient_inconsistency.c b/src/auditordb/pg_update_reserve_balance_insufficient_inconsistency.c deleted file mode 100644 index 93302c51f..000000000 --- a/src/auditordb/pg_update_reserve_balance_insufficient_inconsistency.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - 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 "platform.h" -#include "taler_pq_lib.h" -#include "pg_helper.h" - -#include "pg_update_reserve_balance_insufficient_inconsistency.h" - -/* -Update a given resource – for now this only means suppressing -*/ -enum GNUNET_DB_QueryStatus -TAH_PG_update_reserve_balance_insufficient_inconsistency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&gu->row_id), - GNUNET_PQ_query_param_bool (gu->suppressed), - GNUNET_PQ_query_param_end - }; - - - PREPARE (pg, - "update_reserve_balance_insufficient_inconsistency", - "UPDATE auditor_reserve_balance_insufficient_inconsistency SET" - " suppressed=$2" - " WHERE row_id=$1"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_reserve_balance_insufficient_inconsistency", - params); -} diff --git a/src/auditordb/pg_update_reserve_balance_insufficient_inconsistency.h b/src/auditordb/pg_update_reserve_balance_insufficient_inconsistency.h deleted file mode 100644 index ccc8d0715..000000000 --- a/src/auditordb/pg_update_reserve_balance_insufficient_inconsistency.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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 SRC_PG_UPDATE_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_H -#define SRC_PG_UPDATE_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_update_reserve_balance_insufficient_inconsistency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *dc); - -#endif // SRC_PG_UPDATE_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_H diff --git a/src/auditordb/pg_update_reserve_balance_summary_wrong_inconsistency.c b/src/auditordb/pg_update_reserve_balance_summary_wrong_inconsistency.c deleted file mode 100644 index ff95de80c..000000000 --- a/src/auditordb/pg_update_reserve_balance_summary_wrong_inconsistency.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - 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 "platform.h" -#include "taler_pq_lib.h" -#include "pg_helper.h" - -#include "pg_update_reserve_balance_summary_wrong_inconsistency.h" - -/* -Update a given resource – for now this only means suppressing -*/ -enum GNUNET_DB_QueryStatus -TAH_PG_update_reserve_balance_summary_wrong_inconsistency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&gu->row_id), - GNUNET_PQ_query_param_bool (gu->suppressed), - GNUNET_PQ_query_param_end - }; - - - PREPARE (pg, - "update_reserve_balance_summary_wrong_inconsistency", - "UPDATE auditor_reserve_balance_summary_wrong_inconsistency SET" - " suppressed=$2" - " WHERE row_id=$1"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_reserve_balance_summary_wrong_inconsistency", - params); -} diff --git a/src/auditordb/pg_update_reserve_balance_summary_wrong_inconsistency.h b/src/auditordb/pg_update_reserve_balance_summary_wrong_inconsistency.h deleted file mode 100644 index 341acac1e..000000000 --- a/src/auditordb/pg_update_reserve_balance_summary_wrong_inconsistency.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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 SRC_PG_UPDATE_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_H -#define SRC_PG_UPDATE_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_update_reserve_balance_summary_wrong_inconsistency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *dc); - -#endif // SRC_PG_UPDATE_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_H diff --git a/src/auditordb/pg_update_reserve_in_inconsistency.c b/src/auditordb/pg_update_reserve_in_inconsistency.c deleted file mode 100644 index f905e3750..000000000 --- a/src/auditordb/pg_update_reserve_in_inconsistency.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - 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 "platform.h" -#include "taler_pq_lib.h" -#include "pg_helper.h" - -#include "pg_update_reserve_in_inconsistency.h" - -/* -Update a given resource – for now this only means suppressing -*/ -enum GNUNET_DB_QueryStatus -TAH_PG_update_reserve_in_inconsistency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&gu->row_id), - GNUNET_PQ_query_param_bool (gu->suppressed), - GNUNET_PQ_query_param_end - }; - - - PREPARE (pg, - "update_reserve_in_inconsistency", - "UPDATE auditor_reserve_in_inconsistency SET" - " suppressed=$2" - " WHERE row_id=$1"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_reserve_in_inconsistency", - params); -} diff --git a/src/auditordb/pg_update_reserve_in_inconsistency.h b/src/auditordb/pg_update_reserve_in_inconsistency.h deleted file mode 100644 index 5eacb68da..000000000 --- a/src/auditordb/pg_update_reserve_in_inconsistency.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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 SRC_PG_UPDATE_RESERVE_IN_INCONSISTENCY_H -#define SRC_PG_UPDATE_RESERVE_IN_INCONSISTENCY_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_update_reserve_in_inconsistency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *dc); - -#endif // SRC_PG_UPDATE_RESERVE_IN_INCONSISTENCY_H diff --git a/src/auditordb/pg_update_reserve_not_closed_inconsistency.c b/src/auditordb/pg_update_reserve_not_closed_inconsistency.c deleted file mode 100644 index 4eea64fee..000000000 --- a/src/auditordb/pg_update_reserve_not_closed_inconsistency.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - 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 "platform.h" -#include "taler_pq_lib.h" -#include "pg_helper.h" - -#include "pg_update_reserve_not_closed_inconsistency.h" - -/* -Update a given resource – for now this only means suppressing -*/ -enum GNUNET_DB_QueryStatus -TAH_PG_update_reserve_not_closed_inconsistency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&gu->row_id), - GNUNET_PQ_query_param_bool (gu->suppressed), - GNUNET_PQ_query_param_end - }; - - - PREPARE (pg, - "update_reserve_not_closed_inconsistency", - "UPDATE auditor_reserve_not_closed_inconsistency SET" - " suppressed=$2" - " WHERE row_id=$1"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_reserve_not_closed_inconsistency", - params); -} diff --git a/src/auditordb/pg_update_reserve_not_closed_inconsistency.h b/src/auditordb/pg_update_reserve_not_closed_inconsistency.h deleted file mode 100644 index 4739bc5f6..000000000 --- a/src/auditordb/pg_update_reserve_not_closed_inconsistency.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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 SRC_PG_UPDATE_RESERVE_NOT_CLOSED_INCONSISTENCY_H -#define SRC_PG_UPDATE_RESERVE_NOT_CLOSED_INCONSISTENCY_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_update_reserve_not_closed_inconsistency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *dc); - -#endif // SRC_PG_UPDATE_RESERVE_NOT_CLOSED_INCONSISTENCY_H diff --git a/src/auditordb/pg_update_row_inconsistency.c b/src/auditordb/pg_update_row_inconsistency.c deleted file mode 100644 index 985f7e2ee..000000000 --- a/src/auditordb/pg_update_row_inconsistency.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - 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 "platform.h" -#include "taler_pq_lib.h" -#include "pg_helper.h" - -#include "pg_update_row_inconsistency.h" - -/* -Update a given resource – for now this only means suppressing -*/ -enum GNUNET_DB_QueryStatus -TAH_PG_update_row_inconsistency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&gu->row_id), - GNUNET_PQ_query_param_bool (gu->suppressed), - GNUNET_PQ_query_param_end - }; - - - PREPARE (pg, - "update_row_inconsistency", - "UPDATE auditor_row_inconsistency SET" - " suppressed=$2" - " WHERE row_id=$1"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_row_inconsistency", - params); -} diff --git a/src/auditordb/pg_update_row_inconsistency.h b/src/auditordb/pg_update_row_inconsistency.h deleted file mode 100644 index d6431558f..000000000 --- a/src/auditordb/pg_update_row_inconsistency.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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 SRC_PG_UPDATE_ROW_INCONSISTENCY_H -#define SRC_PG_UPDATE_ROW_INCONSISTENCY_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_update_row_inconsistency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *dc); - -#endif // SRC_PG_UPDATE_ROW_INCONSISTENCY_H diff --git a/src/auditordb/pg_update_row_minor_inconsistencies.c b/src/auditordb/pg_update_row_minor_inconsistencies.c deleted file mode 100644 index 36ba5d62f..000000000 --- a/src/auditordb/pg_update_row_minor_inconsistencies.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - 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 "platform.h" -#include "taler_pq_lib.h" -#include "pg_helper.h" - -#include "pg_update_row_minor_inconsistencies.h" - -/* -Update a given resource – for now this only means suppressing -*/ -enum GNUNET_DB_QueryStatus -TAH_PG_update_row_minor_inconsistencies ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&gu->row_id), - GNUNET_PQ_query_param_bool (gu->suppressed), - GNUNET_PQ_query_param_end - }; - - - PREPARE (pg, - "update_row_minor_inconsistencies", - "UPDATE auditor_row_minor_inconsistencies SET" - " suppressed=$2" - " WHERE row_id=$1"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_row_minor_inconsistencies", - params); -} diff --git a/src/auditordb/pg_update_row_minor_inconsistencies.h b/src/auditordb/pg_update_row_minor_inconsistencies.h deleted file mode 100644 index fccb9fa99..000000000 --- a/src/auditordb/pg_update_row_minor_inconsistencies.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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 SRC_PG_UPDATE_ROW_MINOR_INCONSISTENCIES_H -#define SRC_PG_UPDATE_ROW_MINOR_INCONSISTENCIES_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_update_row_minor_inconsistencies ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *dc); - -#endif // SRC_PG_UPDATE_ROW_MINOR_INCONSISTENCIES_H diff --git a/src/auditordb/pg_update_wire_format_inconsistency.c b/src/auditordb/pg_update_wire_format_inconsistency.c deleted file mode 100644 index 70953582d..000000000 --- a/src/auditordb/pg_update_wire_format_inconsistency.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - 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 "platform.h" -#include "taler_pq_lib.h" -#include "pg_helper.h" - -#include "pg_update_wire_format_inconsistency.h" - -/* -Update a given resource – for now this only means suppressing -*/ -enum GNUNET_DB_QueryStatus -TAH_PG_update_wire_format_inconsistency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&gu->row_id), - GNUNET_PQ_query_param_bool (gu->suppressed), - GNUNET_PQ_query_param_end - }; - - - PREPARE (pg, - "update_wire_format_inconsistency", - "UPDATE auditor_wire_format_inconsistency SET" - " suppressed=$2" - " WHERE row_id=$1"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_wire_format_inconsistency", - params); -} diff --git a/src/auditordb/pg_update_wire_format_inconsistency.h b/src/auditordb/pg_update_wire_format_inconsistency.h deleted file mode 100644 index 32a612afc..000000000 --- a/src/auditordb/pg_update_wire_format_inconsistency.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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 SRC_PG_UPDATE_WIRE_FORMAT_INCONSISTENCY_H -#define SRC_PG_UPDATE_WIRE_FORMAT_INCONSISTENCY_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_update_wire_format_inconsistency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *dc); - -#endif // SRC_PG_UPDATE_WIRE_FORMAT_INCONSISTENCY_H diff --git a/src/auditordb/pg_update_wire_out_inconsistency.c b/src/auditordb/pg_update_wire_out_inconsistency.c deleted file mode 100644 index 543ce3cc6..000000000 --- a/src/auditordb/pg_update_wire_out_inconsistency.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - 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 "platform.h" -#include "taler_pq_lib.h" -#include "pg_helper.h" - -#include "pg_update_wire_out_inconsistency.h" - -/* -Update a given resource – for now this only means suppressing -*/ -enum GNUNET_DB_QueryStatus -TAH_PG_update_wire_out_inconsistency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&gu->row_id), - GNUNET_PQ_query_param_bool (gu->suppressed), - GNUNET_PQ_query_param_end - }; - - - PREPARE (pg, - "update_wire_out_inconsistency", - "UPDATE auditor_wire_out_inconsistency SET" - " suppressed=$2" - " WHERE row_id=$1"); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_wire_out_inconsistency", - params); -} diff --git a/src/auditordb/pg_update_wire_out_inconsistency.h b/src/auditordb/pg_update_wire_out_inconsistency.h deleted file mode 100644 index 3032a6c0e..000000000 --- a/src/auditordb/pg_update_wire_out_inconsistency.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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 SRC_PG_UPDATE_WIRE_OUT_INCONSISTENCY_H -#define SRC_PG_UPDATE_WIRE_OUT_INCONSISTENCY_H - -#include "taler_util.h" -#include "taler_auditordb_plugin.h" - -enum GNUNET_DB_QueryStatus -TAH_PG_update_wire_out_inconsistency ( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *dc); - -#endif // SRC_PG_UPDATE_WIRE_OUT_INCONSISTENCY_H diff --git a/src/auditordb/plugin_auditordb_postgres.c b/src/auditordb/plugin_auditordb_postgres.c index 0d24b7872..6cbc0bf7b 100644 --- a/src/auditordb/plugin_auditordb_postgres.c +++ b/src/auditordb/plugin_auditordb_postgres.c @@ -23,13 +23,14 @@ #include "taler_pq_lib.h" #include <pthread.h> #include <libpq-fe.h> -#include "pg_delete_deposit_confirmations.h" +#include "pg_delete_generic.h" #include "pg_delete_pending_deposit.h" #include "pg_delete_purse_info.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" @@ -48,6 +49,7 @@ #include "pg_insert_reserve_info.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" @@ -59,122 +61,72 @@ #include "pg_get_amount_arithmetic_inconsistency.h" #include "pg_get_coin_inconsistency.h" #include "pg_get_row_inconsistency.h" -#include "pg_update_emergency_by_count.h" -#include "pg_update_row_inconsistency.h" -#include "pg_update_purse_not_closed_inconsistencies.h" -#include "pg_update_reserve_balance_insufficient_inconsistency.h" -#include "pg_update_coin_inconsistency.h" -#include "pg_update_denomination_key_validity_withdraw_inconsistency.h" -#include "pg_update_refreshes_hanging.h" -#include "pg_update_emergency.h" -#include "pg_update_closure_lags.h" -#include "pg_update_row_minor_inconsistencies.h" - #include "pg_update_balance.h" -#include "pg_del_amount_arithmetic_inconsistency.h" -#include "pg_del_coin_inconsistency.h" -#include "pg_del_row_inconsistency.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_del_auditor_closure_lags.h" #include "pg_insert_auditor_closure_lags.h" #include "pg_get_emergency_by_count.h" -#include "pg_del_emergency_by_count.h" #include "pg_insert_emergency_by_count.h" #include "pg_get_emergency.h" -#include "pg_del_emergency.h" #include "pg_insert_emergency.h" -#include "pg_del_auditor_progress.h" - #include "pg_get_bad_sig_losses.h" -#include "pg_del_bad_sig_losses.h" #include "pg_insert_bad_sig_losses.h" -#include "pg_update_bad_sig_losses.h" #include "pg_get_denomination_key_validity_withdraw_inconsistency.h" -#include "pg_del_denomination_key_validity_withdraw_inconsistency.h" #include "pg_insert_denomination_key_validity_withdraw_inconsistency.h" #include "pg_get_fee_time_inconsistency.h" -#include "pg_del_fee_time_inconsistency.h" #include "pg_insert_fee_time_inconsistency.h" -#include "pg_update_fee_time_inconsistency.h" #include "pg_get_purse_not_closed_inconsistencies.h" -#include "pg_del_purse_not_closed_inconsistencies.h" #include "pg_insert_purse_not_closed_inconsistencies.h" #include "pg_get_refreshes_hanging.h" -#include "pg_del_refreshes_hanging.h" #include "pg_insert_refreshes_hanging.h" #include "pg_get_reserve_balance_insufficient_inconsistency.h" -#include "pg_del_reserve_balance_insufficient_inconsistency.h" #include "pg_insert_reserve_balance_insufficient_inconsistency.h" #include "pg_get_reserve_in_inconsistency.h" -#include "pg_del_reserve_in_inconsistency.h" #include "pg_insert_reserve_in_inconsistency.h" -#include "pg_update_reserve_in_inconsistency.h" #include "pg_get_reserve_not_closed_inconsistency.h" -#include "pg_del_reserve_not_closed_inconsistency.h" #include "pg_insert_reserve_not_closed_inconsistency.h" -#include "pg_update_reserve_not_closed_inconsistency.h" #include "pg_get_denominations_without_sigs.h" -#include "pg_del_denominations_without_sigs.h" #include "pg_insert_denominations_without_sigs.h" -#include "pg_update_denominations_without_sigs.h" #include "pg_get_misattribution_in_inconsistency.h" -#include "pg_del_misattribution_in_inconsistency.h" #include "pg_insert_misattribution_in_inconsistency.h" -#include "pg_update_misattribution_in_inconsistency.h" #include "pg_get_reserves.h" -#include "pg_del_reserves.h" - #include "pg_get_purses.h" -#include "pg_del_purses.h" #include "pg_get_denomination_pending.h" -#include "pg_del_denomination_pending.h" #include "pg_insert_denomination_pending.h" -#include "pg_update_denomination_pending.h" #include "pg_get_exchange_signkeys.h" #include "pg_get_wire_format_inconsistency.h" -#include "pg_del_wire_format_inconsistency.h" #include "pg_insert_wire_format_inconsistency.h" -#include "pg_update_wire_format_inconsistency.h" #include "pg_get_wire_out_inconsistency.h" -#include "pg_del_wire_out_inconsistency.h" #include "pg_insert_wire_out_inconsistency.h" -#include "pg_update_wire_out_inconsistency.h" +#include "pg_delete_wire_out_inconsistency_if_matching.h" #include "pg_get_reserve_balance_summary_wrong_inconsistency.h" -#include "pg_del_reserve_balance_summary_wrong_inconsistency.h" #include "pg_insert_reserve_balance_summary_wrong_inconsistency.h" -#include "pg_update_reserve_balance_summary_wrong_inconsistency.h" #include "pg_get_row_minor_inconsistencies.h" -#include "pg_del_row_minor_inconsistencies.h" #include "pg_insert_row_minor_inconsistencies.h" -#include "pg_update_row_minor_inconsistencies.h" - -#include "pg_update_amount_arithmetic_inconsistency.h" -#include "pg_update_deposit_confirmations.h" #define LOG(kind,...) GNUNET_log_from (kind, "taler-auditordb-postgres", \ __VA_ARGS__) @@ -478,7 +430,7 @@ postgres_rollback (void *cls) * @param cls the `struct PostgresClosure` with the plugin-specific state * @return transaction status code */ -enum GNUNET_DB_QueryStatus +static enum GNUNET_DB_QueryStatus postgres_commit (void *cls) { struct PostgresClosure *pg = cls; @@ -552,6 +504,10 @@ postgres_gc (void *cls) * @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) { const struct GNUNET_CONFIGURATION_Handle *cfg = cls; @@ -587,6 +543,7 @@ libtaler_plugin_auditordb_postgres_init (void *cls) = &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; @@ -594,6 +551,11 @@ libtaler_plugin_auditordb_postgres_init (void *cls) = &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->update_auditor_progress = &TAH_PG_update_auditor_progress; @@ -601,9 +563,6 @@ libtaler_plugin_auditordb_postgres_init (void *cls) = &TAH_PG_insert_deposit_confirmation; plugin->get_deposit_confirmations = &TAH_PG_get_deposit_confirmations; - plugin->delete_deposit_confirmation - = &TAH_PG_delete_deposit_confirmation; - plugin->get_amount_arithmetic_inconsistency = &TAH_PG_get_amount_arithmetic_inconsistency; @@ -613,14 +572,6 @@ libtaler_plugin_auditordb_postgres_init (void *cls) = &TAH_PG_get_row_inconsistency; - plugin->delete_row_inconsistency - = &TAH_PG_del_row_inconsistency; - plugin->delete_coin_inconsistency - = &TAH_PG_del_coin_inconsistency; - plugin->delete_amount_arithmetic_inconsistency - = &TAH_PG_del_amount_arithmetic_inconsistency; - - plugin->insert_amount_arithmetic_inconsistency = &TAH_PG_insert_amount_arithmetic_inconsistency; plugin->insert_coin_inconsistency @@ -676,156 +627,91 @@ libtaler_plugin_auditordb_postgres_init (void *cls) = &TAH_PG_select_historic_reserve_revenue; - plugin->delete_emergency = &TAH_PG_del_emergency; plugin->insert_emergency = &TAH_PG_insert_emergency; plugin->get_emergency = &TAH_PG_get_emergency; - plugin->delete_emergency_by_count = &TAH_PG_del_emergency_by_count; plugin->insert_emergency_by_count = &TAH_PG_insert_emergency_by_count; plugin->get_emergency_by_count = &TAH_PG_get_emergency_by_count; - plugin->delete_denomination_key_validity_withdraw_inconsistency = - &TAH_PG_del_denomination_key_validity_withdraw_inconsistency; 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->delete_purse_not_closed_inconsistencies = - &TAH_PG_del_purse_not_closed_inconsistencies; 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->delete_reserve_balance_insufficient_inconsistency = - &TAH_PG_del_reserve_balance_insufficient_inconsistency; 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->delete_bad_sig_losses = &TAH_PG_del_bad_sig_losses; plugin->insert_bad_sig_losses = &TAH_PG_insert_bad_sig_losses; plugin->get_bad_sig_losses = &TAH_PG_get_bad_sig_losses; - plugin->update_bad_sig_losses = &TAH_PG_update_bad_sig_losses; - plugin->delete_auditor_closure_lags = &TAH_PG_del_auditor_closure_lags; plugin->insert_auditor_closure_lags = &TAH_PG_insert_auditor_closure_lags; plugin->get_auditor_closure_lags = &TAH_PG_get_auditor_closure_lags; - plugin->delete_progress = &TAH_PG_del_progress; - - - plugin->delete_refreshes_hanging = &TAH_PG_del_refreshes_hanging; plugin->insert_refreshes_hanging = &TAH_PG_insert_refreshes_hanging; plugin->get_refreshes_hanging = &TAH_PG_get_refreshes_hanging; - plugin->update_emergency_by_count = &TAH_PG_update_emergency_by_count; - plugin->update_row_inconsistency = &TAH_PG_update_row_inconsistency; - plugin->update_purse_not_closed_inconsistencies = - &TAH_PG_update_purse_not_closed_inconsistencies; - plugin->update_reserve_balance_insufficient_inconsistency = - &TAH_PG_update_reserve_balance_insufficient_inconsistency; - plugin->update_coin_inconsistency = &TAH_PG_update_coin_inconsistency; - plugin->update_denomination_key_validity_withdraw_inconsistency = - &TAH_PG_update_denomination_key_validity_withdraw_inconsistency; - plugin->update_refreshes_hanging = &TAH_PG_update_refreshes_hanging; - plugin->update_emergency = &TAH_PG_update_emergency; - plugin->update_closure_lags = &TAH_PG_update_closure_lags; - - - plugin->delete_reserve_in_inconsistency = - &TAH_PG_del_reserve_in_inconsistency; plugin->insert_reserve_in_inconsistency = &TAH_PG_insert_reserve_in_inconsistency; plugin->get_reserve_in_inconsistency = &TAH_PG_get_reserve_in_inconsistency; - plugin->update_reserve_in_inconsistency = - &TAH_PG_update_reserve_in_inconsistency; - - plugin->delete_reserve_not_closed_inconsistency = - &TAH_PG_del_reserve_not_closed_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->update_reserve_not_closed_inconsistency = - &TAH_PG_update_reserve_not_closed_inconsistency; - - plugin->delete_denominations_without_sigs = - &TAH_PG_del_denominations_without_sigs; plugin->insert_denominations_without_sigs = &TAH_PG_insert_denominations_without_sigs; plugin->get_denominations_without_sigs = &TAH_PG_get_denominations_without_sigs; - plugin->update_denominations_without_sigs = - &TAH_PG_update_denominations_without_sigs; + + plugin->get_progress_points + = &TAH_PG_get_progress_points; - plugin->delete_misattribution_in_inconsistency = - &TAH_PG_del_misattribution_in_inconsistency; plugin->insert_misattribution_in_inconsistency = &TAH_PG_insert_misattribution_in_inconsistency; plugin->get_misattribution_in_inconsistency = &TAH_PG_get_misattribution_in_inconsistency; - plugin->update_misattribution_in_inconsistency = - &TAH_PG_update_misattribution_in_inconsistency; - plugin->delete_reserves = &TAH_PG_del_reserves; plugin->get_reserves = &TAH_PG_get_reserves; - - plugin->delete_purses = &TAH_PG_del_purses; plugin->get_purses = &TAH_PG_get_purses; - plugin->delete_denomination_pending = &TAH_PG_del_denomination_pending; plugin->insert_denomination_pending = &TAH_PG_insert_denomination_pending; plugin->get_denomination_pending = &TAH_PG_get_denomination_pending; - plugin->update_denomination_pending = &TAH_PG_update_denomination_pending; plugin->get_exchange_signkeys = &TAH_PG_get_exchange_signkeys; - plugin->delete_wire_format_inconsistency = - &TAH_PG_del_wire_format_inconsistency; plugin->insert_wire_format_inconsistency = &TAH_PG_insert_wire_format_inconsistency; plugin->get_wire_format_inconsistency = &TAH_PG_get_wire_format_inconsistency; - plugin->update_wire_format_inconsistency = - &TAH_PG_update_wire_format_inconsistency; + plugin->insert_wire_out_inconsistency + = &TAH_PG_insert_wire_out_inconsistency; + plugin->get_wire_out_inconsistency + = &TAH_PG_get_wire_out_inconsistency; - plugin->delete_wire_out_inconsistency = &TAH_PG_del_wire_out_inconsistency; - plugin->insert_wire_out_inconsistency = &TAH_PG_insert_wire_out_inconsistency; - plugin->get_wire_out_inconsistency = &TAH_PG_get_wire_out_inconsistency; - plugin->update_wire_out_inconsistency = &TAH_PG_update_wire_out_inconsistency; - - - plugin->delete_reserve_balance_summary_wrong_inconsistency = - &TAH_PG_del_reserve_balance_summary_wrong_inconsistency; 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->update_reserve_balance_summary_wrong_inconsistency = - &TAH_PG_update_reserve_balance_summary_wrong_inconsistency; - plugin->delete_row_minor_inconsistencies = - &TAH_PG_del_row_minor_inconsistencies; plugin->insert_row_minor_inconsistencies = &TAH_PG_insert_row_minor_inconsistencies; plugin->get_row_minor_inconsistencies = &TAH_PG_get_row_minor_inconsistencies; - plugin->update_row_minor_inconsistencies = - &TAH_PG_update_row_minor_inconsistencies; - plugin->delete_fee_time_inconsistency = &TAH_PG_del_fee_time_inconsistency; plugin->insert_fee_time_inconsistency = &TAH_PG_insert_fee_time_inconsistency; plugin->get_fee_time_inconsistency = &TAH_PG_get_fee_time_inconsistency; - plugin->update_fee_time_inconsistency = &TAH_PG_update_fee_time_inconsistency; plugin->update_balance = &TAH_PG_update_balance; @@ -833,11 +719,6 @@ libtaler_plugin_auditordb_postgres_init (void *cls) plugin->insert_exchange_signkey = &TAH_PG_insert_exchange_signkey; - plugin->update_deposit_confirmations - = &TAH_PG_update_deposit_confirmations; - plugin->update_amount_arithmetic_inconsistency - = &TAH_PG_update_amount_arithmetic_inconsistency; - return plugin; } @@ -849,6 +730,10 @@ libtaler_plugin_auditordb_postgres_init (void *cls) * @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) { struct TALER_AUDITORDB_Plugin *plugin = cls; diff --git a/src/auditordb/restart.sql b/src/auditordb/restart.sql index 2dc6864ff..d13d3acd1 100644 --- a/src/auditordb/restart.sql +++ b/src/auditordb/restart.sql @@ -32,13 +32,34 @@ SET search_path TO auditor; -- latest requirements for dropping tables. DELETE FROM auditor_amount_arithmetic_inconsistency; +DELETE FROM auditor_bad_sig_losses; DELETE FROM auditor_balances; +DELETE FROM auditor_closure_lags; +DELETE FROM auditor_coin_inconsistency; +DELETE FROM auditor_denomination_key_validity_withdraw_inconsistency; DELETE FROM auditor_denomination_pending; +DELETE FROM auditor_denominations_without_sigs; +DELETE FROM auditor_emergency; +DELETE FROM auditor_emergency_by_count; +DELETE FROM auditor_fee_time_inconsistency; DELETE FROM auditor_historic_denomination_revenue; DELETE FROM auditor_historic_reserve_summary; +DELETE FROM auditor_misattribution_in_inconsistency; +DELETE FROM auditor_pending_deposits; DELETE FROM auditor_progress; +DELETE FROM auditor_purse_not_closed_inconsistencies; DELETE FROM auditor_purses; +DELETE FROM auditor_refreshes_hanging; +DELETE FROM auditor_reserve_balance_insufficient_inconsistency; +DELETE FROM auditor_reserve_balance_summary_wrong_inconsistency; +DELETE FROM auditor_reserve_in_inconsistency; +DELETE FROM auditor_reserve_not_closed_inconsistency; DELETE FROM auditor_reserves; +DELETE FROM auditor_row_inconsistency; +DELETE FROM auditor_row_minor_inconsistencies; +DELETE FROM auditor_wire_format_inconsistency; +DELETE FROM auditor_wire_out_inconsistency; + -- And we're out of here... COMMIT; diff --git a/src/auditordb/test_auditordb.c b/src/auditordb/test_auditordb.c index b72e95ab1..c859e7239 100644 --- a/src/auditordb/test_auditordb.c +++ b/src/auditordb/test_auditordb.c @@ -106,6 +106,7 @@ static struct TALER_Amount reserve_profits; static enum GNUNET_GenericReturnValue select_historic_denom_revenue_result ( void *cls, + uint64_t rowid, const struct TALER_DenominationHashP *denom_pub_hash2, struct GNUNET_TIME_Timestamp revenue_timestamp2, const struct TALER_Amount *revenue_balance2, @@ -144,6 +145,7 @@ select_historic_denom_revenue_result ( static enum GNUNET_GenericReturnValue select_historic_reserve_revenue_result ( void *cls, + uint64_t rowid, struct GNUNET_TIME_Timestamp start_time2, struct GNUNET_TIME_Timestamp end_time2, const struct TALER_Amount *reserve_profits2) @@ -183,6 +185,15 @@ run (void *cls) { struct GNUNET_CONFIGURATION_Handle *cfg = cls; uint64_t rowid; + struct TALER_Amount value; + struct TALER_Amount fee_withdraw; + struct TALER_Amount fee_deposit; + struct TALER_Amount fee_refresh; + struct TALER_Amount fee_refund; + struct TALER_ReservePublicKeyP reserve_pub; + struct TALER_DenominationPrivateKey denom_priv; + struct TALER_DenominationPublicKey denom_pub; + struct GNUNET_TIME_Timestamp date; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "loading database plugin\n"); @@ -217,12 +228,6 @@ run (void *cls) GNUNET_log (GNUNET_ERROR_TYPE_INFO, "initializing\n"); - struct TALER_Amount value; - struct TALER_Amount fee_withdraw; - struct TALER_Amount fee_deposit; - struct TALER_Amount fee_refresh; - struct TALER_Amount fee_refund; - GNUNET_assert (GNUNET_OK == TALER_string_to_amount (CURRENCY ":1.000010", &value)); @@ -238,12 +243,6 @@ run (void *cls) GNUNET_assert (GNUNET_OK == TALER_string_to_amount (CURRENCY ":0.000014", &fee_refund)); - - struct TALER_ReservePublicKeyP reserve_pub; - struct TALER_DenominationPrivateKey denom_priv; - struct TALER_DenominationPublicKey denom_pub; - struct GNUNET_TIME_Timestamp date; - RND_BLK (&reserve_pub); RND_BLK (&rnd_hash); GNUNET_assert (GNUNET_OK == @@ -414,6 +413,8 @@ run (void *cls) FAILIF (0 >= plugin->select_historic_denom_revenue ( plugin->cls, + 0, + 1024, &select_historic_denom_revenue_result, NULL)); GNUNET_log (GNUNET_ERROR_TYPE_INFO, @@ -434,9 +435,12 @@ run (void *cls) GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Test: select_historic_reserve_revenue\n"); FAILIF (0 >= - plugin->select_historic_reserve_revenue (plugin->cls, - select_historic_reserve_revenue_result, - NULL)); + plugin->select_historic_reserve_revenue ( + plugin->cls, + 0, + 1024, + &select_historic_reserve_revenue_result, + NULL)); FAILIF (0 > plugin->commit (plugin->cls)); diff --git a/src/auditordb/test_auditordb_checkpoints.c b/src/auditordb/test_auditordb_checkpoints.c index 639868867..2000a674a 100644 --- a/src/auditordb/test_auditordb_checkpoints.c +++ b/src/auditordb/test_auditordb_checkpoints.c @@ -179,15 +179,23 @@ run (void *cls) * Test3 = 245 * Let's make sure that's the case! */ uint64_t value; + uint64_t valueNX; + uint64_t value3; GNUNET_assert ( - GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == + 3 == plugin->get_auditor_progress ( plugin->cls, "Test", &value, + "TestNX", + &valueNX, + "Test3", + &value3, NULL) ); GNUNET_assert (value == 42); + GNUNET_assert (valueNX == 0); + GNUNET_assert (value3 == 245); /* Ensure the rest are also at their expected values */ GNUNET_assert ( @@ -323,8 +331,7 @@ run (void *cls) &a1, NULL) ); - GNUNET_assert (GNUNET_OK != - TALER_amount_is_valid (&a1)); + GNUNET_assert (TALER_amount_is_zero (&a1)); result = 0; GNUNET_break (0 <= diff --git a/src/bank-lib/bank_api_credit.c b/src/bank-lib/bank_api_credit.c index 29becbfa9..dc92b064a 100644 --- a/src/bank-lib/bank_api_credit.c +++ b/src/bank-lib/bank_api_credit.c @@ -86,8 +86,8 @@ parse_account_history (struct TALER_BANK_CreditHistoryHandle *hh, struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_array_const ("incoming_transactions", &history_array), - GNUNET_JSON_spec_string ("credit_account", - &chr.details.ok.credit_account_uri), + TALER_JSON_spec_payto_uri ("credit_account", + &chr.details.ok.credit_account_uri), GNUNET_JSON_spec_end () }; @@ -118,8 +118,8 @@ parse_account_history (struct TALER_BANK_CreditHistoryHandle *hh, &td->execution_date), GNUNET_JSON_spec_uint64 ("row_id", &td->serial_id), - GNUNET_JSON_spec_string ("debit_account", - &td->debit_account_uri), + TALER_JSON_spec_payto_uri ("debit_account", + &td->debit_account_uri), GNUNET_JSON_spec_end () }; json_t *transaction = json_array_get (history_array, @@ -178,7 +178,7 @@ parse_account_history (struct TALER_BANK_CreditHistoryHandle *hh, type)) { struct GNUNET_JSON_Specification wad_spec[] = { - GNUNET_JSON_spec_string ("origin_exchange_url", + TALER_JSON_spec_web_url ("origin_exchange_url", &td->details.wad.origin_exchange_url), GNUNET_JSON_spec_fixed_auto ("wad_id", &td->details.wad.wad_id), diff --git a/src/bank-lib/bank_api_debit.c b/src/bank-lib/bank_api_debit.c index 58dc0a736..62bf66c0f 100644 --- a/src/bank-lib/bank_api_debit.c +++ b/src/bank-lib/bank_api_debit.c @@ -86,8 +86,8 @@ parse_account_history (struct TALER_BANK_DebitHistoryHandle *hh, struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_array_const ("outgoing_transactions", &history_array), - GNUNET_JSON_spec_string ("debit_account", - &dhr.details.ok.debit_account_uri), + TALER_JSON_spec_payto_uri ("debit_account", + &dhr.details.ok.debit_account_uri), GNUNET_JSON_spec_end () }; @@ -117,9 +117,9 @@ parse_account_history (struct TALER_BANK_DebitHistoryHandle *hh, &td->serial_id), GNUNET_JSON_spec_fixed_auto ("wtid", &td->wtid), - GNUNET_JSON_spec_string ("credit_account", - &td->credit_account_uri), - GNUNET_JSON_spec_string ("exchange_base_url", + TALER_JSON_spec_payto_uri ("credit_account", + &td->credit_account_uri), + TALER_JSON_spec_web_url ("exchange_base_url", &td->exchange_base_url), GNUNET_JSON_spec_end () }; diff --git a/src/bank-lib/fakebank.h b/src/bank-lib/fakebank.h index 87c7a4af1..8cbf60403 100644 --- a/src/bank-lib/fakebank.h +++ b/src/bank-lib/fakebank.h @@ -159,7 +159,7 @@ struct WithdrawalOperation uint64_t row_id; /** - * Amount transferred. + * Amount transferred, NULL if still unknown. */ struct TALER_Amount *amount; diff --git a/src/bank-lib/fakebank_bank.c b/src/bank-lib/fakebank_bank.c index 96100943c..dcbe4a26c 100644 --- a/src/bank-lib/fakebank_bank.c +++ b/src/bank-lib/fakebank_bank.c @@ -72,7 +72,7 @@ TALER_FAKEBANK_bank_main_ ( connection, MHD_HTTP_OK, GNUNET_JSON_pack_string ("version", - "4:1:4"), /* not sure, API versions are not properly marked up! */ + "4:1:4"), GNUNET_JSON_pack_string ("currency", h->currency), GNUNET_JSON_pack_string ("implementation", diff --git a/src/bank-lib/fakebank_bank_get_root.c b/src/bank-lib/fakebank_bank_get_root.c index 8c34697b4..ef2247e36 100644 --- a/src/bank-lib/fakebank_bank_get_root.c +++ b/src/bank-lib/fakebank_bank_get_root.c @@ -46,10 +46,9 @@ TALER_FAKEBANK_bank_get_root_ (struct TALER_FAKEBANK_Handle *h, #define HELLOMSG "Hello, Fakebank!" (void) h; - resp = MHD_create_response_from_buffer ( + resp = MHD_create_response_from_buffer_static ( strlen (HELLOMSG), - HELLOMSG, - MHD_RESPMEM_MUST_COPY); + HELLOMSG); ret = MHD_queue_response (connection, MHD_HTTP_OK, resp); diff --git a/src/bank-lib/fakebank_bank_post_withdrawals_id_op.c b/src/bank-lib/fakebank_bank_post_withdrawals_id_op.c index 2adc07df0..1b81c8670 100644 --- a/src/bank-lib/fakebank_bank_post_withdrawals_id_op.c +++ b/src/bank-lib/fakebank_bank_post_withdrawals_id_op.c @@ -41,6 +41,7 @@ * @param connection the connection * @param account name of the account * @param withdrawal_id the withdrawal operation identifier + * @param body uploaded JSON body, NULL if none * @return MHD result code */ static MHD_RESULT @@ -48,10 +49,32 @@ bank_withdrawals_confirm ( struct TALER_FAKEBANK_Handle *h, struct MHD_Connection *connection, const char *account, - const char *withdrawal_id) + const char *withdrawal_id, + const json_t *body) { const struct Account *acc; struct WithdrawalOperation *wo; + struct TALER_Amount amount; + bool amount_missing = true; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_mark_optional ( + TALER_JSON_spec_amount ("amount", + h->currency, + &amount), + &amount_missing), + GNUNET_JSON_spec_end () + }; + enum GNUNET_GenericReturnValue ret; + + if ( (NULL != body) && + (GNUNET_OK != + (ret = TALER_MHD_parse_json_data (connection, + body, + spec))) ) + { + GNUNET_break_op (0); + return (GNUNET_NO == ret) ? MHD_YES : MHD_NO; + } GNUNET_assert (0 == pthread_mutex_lock (&h->big_lock)); @@ -91,14 +114,33 @@ bank_withdrawals_confirm ( TALER_EC_BANK_POST_WITHDRAWAL_OPERATION_REQUIRED, NULL); } - if (NULL == wo->amount) + if ( (NULL != wo->amount) && + (! amount_missing) && + (0 != TALER_amount_cmp (&amount, + wo->amount)) ) { GNUNET_assert (0 == pthread_mutex_unlock (&h->big_lock)); return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_BANK_POST_WITHDRAWAL_OPERATION_REQUIRED, - NULL); + MHD_HTTP_CONFLICT, + TALER_EC_BANK_CONFIRM_ABORT_CONFLICT, + "amount inconsistent"); + } + if ( (NULL == wo->amount) && + (amount_missing) ) + { + GNUNET_assert (0 == + pthread_mutex_unlock (&h->big_lock)); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_CONFLICT, + TALER_EC_BANK_CONFIRM_ABORT_CONFLICT, + "amount required"); + } + if (NULL == wo->amount) + { + GNUNET_assert (! amount_missing); + wo->amount = GNUNET_new (struct TALER_Amount); + *wo->amount = amount; } if (wo->aborted) { @@ -152,6 +194,7 @@ bank_withdrawals_confirm ( * @param connection the connection * @param account name of the account * @param withdrawal_id the withdrawal operation identifier + * @param body uploaded JSON body, NULL if none * @return MHD result code */ static MHD_RESULT @@ -159,7 +202,8 @@ bank_withdrawals_abort ( struct TALER_FAKEBANK_Handle *h, struct MHD_Connection *connection, const char *account, - const char *withdrawal_id) + const char *withdrawal_id, + const json_t *body) { struct WithdrawalOperation *wo; const struct Account *acc; @@ -226,23 +270,71 @@ TALER_FAKEBANK_bank_withdrawals_id_op_ ( size_t *upload_data_size, void **con_cls) { + struct ConnectionContext *cc = *con_cls; + json_t *json = NULL; + + if (NULL == cc) + { + cc = GNUNET_new (struct ConnectionContext); + cc->ctx_cleaner = &GNUNET_JSON_post_parser_cleanup; + *con_cls = cc; + } + if (0 != *upload_data_size) + { + enum GNUNET_JSON_PostResult pr; + + pr = GNUNET_JSON_post_parser (REQUEST_BUFFER_MAX, + connection, + &cc->ctx, + upload_data, + upload_data_size, + &json); + switch (pr) + { + case GNUNET_JSON_PR_OUT_OF_MEMORY: + GNUNET_break (0); + return MHD_NO; + case GNUNET_JSON_PR_CONTINUE: + return MHD_YES; + case GNUNET_JSON_PR_REQUEST_TOO_LARGE: + GNUNET_break (0); + return MHD_NO; + case GNUNET_JSON_PR_JSON_INVALID: + GNUNET_break (0); + return MHD_NO; + case GNUNET_JSON_PR_SUCCESS: + break; + } + } + if (0 == strcmp (op, "/confirm")) { - return bank_withdrawals_confirm (h, - connection, - account, - withdrawal_id); + MHD_RESULT res; + + res = bank_withdrawals_confirm (h, + connection, + account, + withdrawal_id, + json); + json_decref (json); + return res; } if (0 == strcmp (op, "/abort")) { - return bank_withdrawals_abort (h, - connection, - account, - withdrawal_id); + MHD_RESULT res; + + res = bank_withdrawals_abort (h, + connection, + account, + withdrawal_id, + json); + json_decref (json); + return res; } GNUNET_break_op (0); + json_decref (json); return TALER_MHD_reply_with_error (connection, MHD_HTTP_NOT_FOUND, TALER_EC_GENERIC_ENDPOINT_UNKNOWN, diff --git a/src/bank-lib/fakebank_common_lp.c b/src/bank-lib/fakebank_common_lp.c index 22a9e3ab4..e73ed4593 100644 --- a/src/bank-lib/fakebank_common_lp.c +++ b/src/bank-lib/fakebank_common_lp.c @@ -32,6 +32,7 @@ #include "taler_mhd_lib.h" #include <gnunet/gnunet_mhd_compat.h> #include "fakebank.h" +#include "fakebank_common_lp.h" void diff --git a/src/bank-lib/fakebank_common_make_admin_transfer.c b/src/bank-lib/fakebank_common_make_admin_transfer.c index 865eaa640..984a4d19f 100644 --- a/src/bank-lib/fakebank_common_make_admin_transfer.c +++ b/src/bank-lib/fakebank_common_make_admin_transfer.c @@ -28,6 +28,7 @@ #include "taler_mhd_lib.h" #include <gnunet/gnunet_mhd_compat.h> #include "fakebank.h" +#include "fakebank_common_make_admin_transfer.h" #include "fakebank_common_lookup.h" #include "fakebank_common_lp.h" #include "fakebank_common_transact.h" @@ -90,20 +91,27 @@ TALER_FAKEBANK_make_admin_transfer_ ( *timestamp = t->date; t->type = T_CREDIT; t->subject.credit.reserve_pub = *reserve_pub; - TALER_FAKEBANK_transact_ (h, - t); - if (NULL != row_id) - *row_id = t->row_id; GNUNET_assert (0 == pthread_mutex_lock (&h->rpubs_lock)); - GNUNET_assert (GNUNET_OK == - GNUNET_CONTAINER_multipeermap_put ( - h->rpubs, - pid, - t, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); + if (GNUNET_OK != + GNUNET_CONTAINER_multipeermap_put ( + h->rpubs, + pid, + t, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) + { + /* duplicate reserve public key not allowed */ + GNUNET_break_op (0); + GNUNET_free (t); + GNUNET_assert (0 == + pthread_mutex_unlock (&h->rpubs_lock)); + } GNUNET_assert (0 == pthread_mutex_unlock (&h->rpubs_lock)); + TALER_FAKEBANK_transact_ (h, + t); + if (NULL != row_id) + *row_id = t->row_id; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Making transfer from %s to %s over %s and subject %s at row %llu\n", debit_account, @@ -151,19 +159,6 @@ TALER_FAKEBANK_make_kycauth_transfer_ ( credit_acc = TALER_FAKEBANK_lookup_account_ (h, credit_account, credit_account); - GNUNET_assert (0 == - pthread_mutex_lock (&h->rpubs_lock)); - t = GNUNET_CONTAINER_multipeermap_get (h->rpubs, - pid); - GNUNET_assert (0 == - pthread_mutex_unlock (&h->rpubs_lock)); - if (NULL != t) - { - /* duplicate reserve public key not allowed */ - GNUNET_break_op (0); - return GNUNET_NO; - } - t = GNUNET_new (struct Transaction); t->unchecked = true; t->debit_account = debit_acc; @@ -178,16 +173,6 @@ TALER_FAKEBANK_make_kycauth_transfer_ ( t); if (NULL != row_id) *row_id = t->row_id; - GNUNET_assert (0 == - pthread_mutex_lock (&h->rpubs_lock)); - GNUNET_assert (GNUNET_OK == - GNUNET_CONTAINER_multipeermap_put ( - h->rpubs, - pid, - t, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); - GNUNET_assert (0 == - pthread_mutex_unlock (&h->rpubs_lock)); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Making transfer from %s to %s over %s and subject %s at row %llu\n", debit_account, diff --git a/src/bank-lib/fakebank_common_parser.c b/src/bank-lib/fakebank_common_parser.c index cf2dc5a74..82836359a 100644 --- a/src/bank-lib/fakebank_common_parser.c +++ b/src/bank-lib/fakebank_common_parser.c @@ -27,6 +27,7 @@ #include "taler_mhd_lib.h" #include <gnunet/gnunet_mhd_compat.h> #include "fakebank.h" +#include "fakebank_common_parser.h" enum GNUNET_GenericReturnValue diff --git a/src/bank-lib/fakebank_tbi_get_withdrawal_operation.c b/src/bank-lib/fakebank_tbi_get_withdrawal_operation.c index fd6f3b7c4..63c247db1 100644 --- a/src/bank-lib/fakebank_tbi_get_withdrawal_operation.c +++ b/src/bank-lib/fakebank_tbi_get_withdrawal_operation.c @@ -120,6 +120,8 @@ TALER_FAKEBANK_tbi_get_withdrawal_operation_ ( wc->wo->confirmation_done), GNUNET_JSON_pack_string ("status", status_string), + GNUNET_JSON_pack_string ("sender_wire", + wc->wo->debit_account->payto_uri), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_string ("suggested_exchange", h->exchange_url)), diff --git a/src/bank-lib/fakebank_tbr.c b/src/bank-lib/fakebank_tbr.c index 0f0e5bdc1..4de6028a9 100644 --- a/src/bank-lib/fakebank_tbr.c +++ b/src/bank-lib/fakebank_tbr.c @@ -27,6 +27,7 @@ #include "taler_mhd_lib.h" #include <gnunet/gnunet_mhd_compat.h> #include "fakebank.h" +#include "fakebank_tbr.h" #include "fakebank_tbr_get_history.h" #include "fakebank_tbr_get_root.h" diff --git a/src/bank-lib/fakebank_tbr_get_history.c b/src/bank-lib/fakebank_tbr_get_history.c index a6cfaad8d..f6aa8f5cc 100644 --- a/src/bank-lib/fakebank_tbr_get_history.c +++ b/src/bank-lib/fakebank_tbr_get_history.c @@ -296,7 +296,7 @@ finish: 0); } { - json_t *h = hc->history; + json_t *jh = hc->history; hc->history = NULL; return TALER_MHD_REPLY_JSON_PACK ( @@ -307,6 +307,6 @@ finish: acc_payto_uri), GNUNET_JSON_pack_array_steal ( "incoming_transactions", - h)); + jh)); } } diff --git a/src/bank-lib/fakebank_tbr_get_root.c b/src/bank-lib/fakebank_tbr_get_root.c index 6e518d661..17591da18 100644 --- a/src/bank-lib/fakebank_tbr_get_root.c +++ b/src/bank-lib/fakebank_tbr_get_root.c @@ -27,6 +27,7 @@ #include "taler_mhd_lib.h" #include <gnunet/gnunet_mhd_compat.h> #include "fakebank.h" +#include "fakebank_tbr_get_root.h" MHD_RESULT @@ -38,10 +39,9 @@ TALER_FAKEBANK_tbr_get_root (struct TALER_FAKEBANK_Handle *h, #define HELLOMSG "Hello, Fakebank (Bank Revenue API here)!" (void) h; - resp = MHD_create_response_from_buffer ( + resp = MHD_create_response_from_buffer_static ( strlen (HELLOMSG), - HELLOMSG, - MHD_RESPMEM_MUST_COPY); + HELLOMSG); ret = MHD_queue_response (connection, MHD_HTTP_OK, resp); diff --git a/src/bank-lib/fakebank_twg_get_root.c b/src/bank-lib/fakebank_twg_get_root.c index 09589890e..af40ed820 100644 --- a/src/bank-lib/fakebank_twg_get_root.c +++ b/src/bank-lib/fakebank_twg_get_root.c @@ -27,6 +27,7 @@ #include "taler_mhd_lib.h" #include <gnunet/gnunet_mhd_compat.h> #include "fakebank.h" +#include "fakebank_twg_get_root.h" /** @@ -46,10 +47,9 @@ TALER_FAKEBANK_twg_get_root_ ( #define HELLOMSG "Hello, Fakebank (Taler Wire Gateway)!" (void) h; - resp = MHD_create_response_from_buffer ( + resp = MHD_create_response_from_buffer_static ( strlen (HELLOMSG), - HELLOMSG, - MHD_RESPMEM_MUST_COPY); + HELLOMSG); ret = MHD_queue_response (connection, MHD_HTTP_OK, resp); diff --git a/src/bank-lib/fakebank_twg_get_transfers.c b/src/bank-lib/fakebank_twg_get_transfers.c index 18b66dd54..ea1064268 100644 --- a/src/bank-lib/fakebank_twg_get_transfers.c +++ b/src/bank-lib/fakebank_twg_get_transfers.c @@ -132,7 +132,8 @@ TALER_FAKEBANK_twg_get_transfers_ ( (t->row_id == offset) ) overflow = true; /* full circle, give up! */ } - if (t->debit_account != acc) + if ( (NULL == t) || + (t->debit_account != acc) ) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid start specified, transaction %llu not with account %s!\n", diff --git a/src/bank-lib/fakebank_twg_history.c b/src/bank-lib/fakebank_twg_history.c index ccb385537..9e5ef3b98 100644 --- a/src/bank-lib/fakebank_twg_history.c +++ b/src/bank-lib/fakebank_twg_history.c @@ -28,6 +28,7 @@ #include "taler_mhd_lib.h" #include <gnunet/gnunet_mhd_compat.h> #include "fakebank.h" +#include "fakebank_twg_history.h" #include "fakebank_common_lookup.h" #include "fakebank_common_lp.h" #include "fakebank_common_parser.h" @@ -288,7 +289,7 @@ finish: 0); } { - json_t *h = hc->history; + json_t *jh = hc->history; hc->history = NULL; return TALER_MHD_REPLY_JSON_PACK ( @@ -299,7 +300,7 @@ finish: acc_payto_uri), GNUNET_JSON_pack_array_steal ( "outgoing_transactions", - h)); + jh)); } } @@ -564,7 +565,7 @@ finish: 0); } { - json_t *h = hc->history; + json_t *jh = hc->history; hc->history = NULL; return TALER_MHD_REPLY_JSON_PACK ( @@ -575,6 +576,6 @@ finish: acc_payto_uri), GNUNET_JSON_pack_array_steal ( "incoming_transactions", - h)); + jh)); } } diff --git a/src/bank-lib/fakebank_twg_transfer.c b/src/bank-lib/fakebank_twg_transfer.c index fef314a52..6a22c7dad 100644 --- a/src/bank-lib/fakebank_twg_transfer.c +++ b/src/bank-lib/fakebank_twg_transfer.c @@ -117,53 +117,49 @@ TALER_FAKEBANK_handle_transfer_ ( json_decref (json); return (GNUNET_NO == ret) ? MHD_YES : MHD_NO; } + credit = TALER_xtalerbank_account_from_payto (credit_account); + if (NULL == credit) { - enum GNUNET_GenericReturnValue ret; - - credit = TALER_xtalerbank_account_from_payto (credit_account); - if (NULL == credit) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error ( - connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PAYTO_URI_MALFORMED, - credit_account); - } - ret = TALER_FAKEBANK_make_transfer_ (h, - account, - credit, - &amount, - &wtid, - base_url, - &uuid, - &row_id, - &ts); - if (GNUNET_OK != ret) - { - MHD_RESULT res; - char *uids; + GNUNET_break_op (0); + return TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PAYTO_URI_MALFORMED, + credit_account); + } + ret = TALER_FAKEBANK_make_transfer_ (h, + account, + credit, + &amount, + &wtid, + base_url, + &uuid, + &row_id, + &ts); + if (GNUNET_OK != ret) + { + MHD_RESULT res; + char *uids; - GNUNET_break (0); - uids = GNUNET_STRINGS_data_to_string_alloc (&uuid, - sizeof (uuid)); - json_decref (json); - res = TALER_MHD_reply_with_error (connection, - MHD_HTTP_CONFLICT, - TALER_EC_BANK_TRANSFER_REQUEST_UID_REUSED, - uids); - GNUNET_free (uids); - return res; - } - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Receiving incoming wire transfer: %s->%s, subject: %s, amount: %s, from %s\n", - account, - credit, - TALER_B2S (&wtid), - TALER_amount2s (&amount), - base_url); - GNUNET_free (credit); + GNUNET_break (0); + uids = GNUNET_STRINGS_data_to_string_alloc (&uuid, + sizeof (uuid)); + json_decref (json); + res = TALER_MHD_reply_with_error (connection, + MHD_HTTP_CONFLICT, + TALER_EC_BANK_TRANSFER_REQUEST_UID_REUSED, + uids); + GNUNET_free (uids); + return res; } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Receiving incoming wire transfer: %s->%s, subject: %s, amount: %s, from %s\n", + account, + credit, + TALER_B2S (&wtid), + TALER_amount2s (&amount), + base_url); + GNUNET_free (credit); } json_decref (json); diff --git a/src/bank-lib/taler-exchange-wire-gateway-client.c b/src/bank-lib/taler-exchange-wire-gateway-client.c index 81b63401c..93837b15d 100644 --- a/src/bank-lib/taler-exchange-wire-gateway-client.c +++ b/src/bank-lib/taler-exchange-wire-gateway-client.c @@ -214,6 +214,7 @@ credit_history_cb (void *cls, TALER_B2S (&cd->details.kycauth.account_pub), TALER_amount2s (&cd->amount), GNUNET_TIME_timestamp2s (cd->execution_date)); + break; case TALER_BANK_CT_WAD: GNUNET_break (0); // FIXME break; @@ -746,10 +747,6 @@ main (int argc, not do this, the linker may "optimize" libtalerutil away and skip #TALER_OS_init(), which we do need */ (void) TALER_project_data_default (); - if (GNUNET_OK != - GNUNET_STRINGS_get_utf8_args (argc, argv, - &argc, &argv)) - return 4; global_ret = 1; ret = GNUNET_PROGRAM_run ( argc, argv, @@ -757,7 +754,6 @@ main (int argc, gettext_noop ("Client tool of the Taler Wire Gateway"), options, &run, NULL); - GNUNET_free_nz ((void *) argv); if (GNUNET_SYSERR == ret) return 3; if (GNUNET_NO == ret) diff --git a/src/benchmark/benchmark-common.conf b/src/benchmark/benchmark-common.conf index e47115a2b..c81ff2814 100644 --- a/src/benchmark/benchmark-common.conf +++ b/src/benchmark/benchmark-common.conf @@ -57,13 +57,13 @@ PAYTO_URI = payto://iban/SANDBOXX/DE033310?receiver-name=Exchange+Company [exchange-accountcredentials-2] WIRE_GATEWAY_AUTH_METHOD = basic USERNAME = exchange -PASSWORD = x +PASSWORD = password WIRE_GATEWAY_URL = "http://localhost:8080/accounts/exchange/taler-wire-gateway/" [admin-accountcredentials-2] WIRE_GATEWAY_AUTH_METHOD = basic USERNAME = admin -PASSWORD = secret +PASSWORD = secret-password WIRE_GATEWAY_URL = "http://localhost:8080/accounts/exchange/taler-wire-gateway/" @@ -95,6 +95,7 @@ RAM_LIMIT=10000000 [libeufin-bank] CURRENCY = EUR +PWD_HASH_CONFIG = { "cost": 4 } [libeufin-nexus] DB_CONNECTION="postgresql:///talercheck" diff --git a/src/benchmark/benchmark-cs.conf b/src/benchmark/benchmark-cs.conf index 7f660ad31..82a97b7e9 100644 --- a/src/benchmark/benchmark-cs.conf +++ b/src/benchmark/benchmark-cs.conf @@ -13,4 +13,4 @@ ENABLE_CREDIT = YES WIRE_GATEWAY_URL = http://localhost:8082/accounts/Exchange/taler-wire-gateway/ WIRE_GATEWAY_AUTH_METHOD = "basic" USERNAME = Exchange -PASSWORD = x +PASSWORD = password diff --git a/src/benchmark/benchmark-rsa.conf b/src/benchmark/benchmark-rsa.conf index a6c1512ee..6ace6478b 100644 --- a/src/benchmark/benchmark-rsa.conf +++ b/src/benchmark/benchmark-rsa.conf @@ -13,4 +13,4 @@ ENABLE_CREDIT = YES WIRE_GATEWAY_URL = http://localhost:8082/accounts/Exchange/taler-wire-gateway/ WIRE_GATEWAY_AUTH_METHOD = "basic" USERNAME = Exchange -PASSWORD = x +PASSWORD = password diff --git a/src/benchmark/taler-aggregator-benchmark.c b/src/benchmark/taler-aggregator-benchmark.c index 228d050e4..fe484e172 100644 --- a/src/benchmark/taler-aggregator-benchmark.c +++ b/src/benchmark/taler-aggregator-benchmark.c @@ -119,7 +119,7 @@ eval_probability (float probability) * @param x pointer to data to randomize */ #define RANDOMIZE(x) \ - GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, x, sizeof (*x)) + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, x, sizeof (*x)) /** @@ -342,7 +342,7 @@ add_deposit (const struct Merchant *m) } } if (GNUNET_YES == - eval_probability (((float) refund_rate) / 100.0)) + eval_probability (((float) refund_rate) / 100.0f)) return add_refund (m, &d); return true; diff --git a/src/benchmark/taler-bank-benchmark.c b/src/benchmark/taler-bank-benchmark.c index 528798424..340ee3349 100644 --- a/src/benchmark/taler-bank-benchmark.c +++ b/src/benchmark/taler-bank-benchmark.c @@ -136,7 +136,7 @@ static struct TALER_TESTING_Timer timings[] = { * @param label string to add to the table * @return same string, now stored in the table */ -const char * +static const char * add_label (char *label) { if (label_off == label_len) diff --git a/src/benchmark/taler-exchange-benchmark.c b/src/benchmark/taler-exchange-benchmark.c index 75424a358..db1fadd1f 100644 --- a/src/benchmark/taler-exchange-benchmark.c +++ b/src/benchmark/taler-exchange-benchmark.c @@ -144,7 +144,7 @@ static struct TALER_TESTING_Timer timings[] = { * @param label string to add to the table * @return same string, now stored in the table */ -const char * +static const char * add_label (char *label) { if (label_off == label_len) @@ -296,7 +296,7 @@ run (void *cls, GNUNET_TIME_UNIT_ZERO, amount_1, MHD_HTTP_OK)); - if (eval_probability (refresh_rate / 100.0)) + if (eval_probability (refresh_rate / 100.0d)) { char *melt_label; char *reveal_label; @@ -630,7 +630,7 @@ main (int argc, " * Reserve=%u * Parallel=%u, operations in %s\n", howmany_coins, howmany_coins, - (float) howmany_coins * (refresh_rate / 100.0), + howmany_coins * (refresh_rate / 100.0d), howmany_reserves, howmany_clients, GNUNET_STRINGS_relative_time_to_string ( diff --git a/src/exchange-tools/.gitignore b/src/exchange-tools/.gitignore index 69279d792..add509a3a 100644 --- a/src/exchange-tools/.gitignore +++ b/src/exchange-tools/.gitignore @@ -1,3 +1,4 @@ taler-exchange-offline taler-auditor-offline taler-crypto-worker +taler-exchange-kyc-trigger diff --git a/src/exchange-tools/Makefile.am b/src/exchange-tools/Makefile.am index 955544564..613a7be99 100644 --- a/src/exchange-tools/Makefile.am +++ b/src/exchange-tools/Makefile.am @@ -14,6 +14,7 @@ endif bin_PROGRAMS = \ taler-auditor-offline \ + taler-exchange-kyc-trigger \ taler-exchange-offline \ taler-exchange-dbinit @@ -31,6 +32,18 @@ taler_exchange_offline_LDADD = \ -lgnunetutil \ $(XLIB) +taler_exchange_kyc_trigger_SOURCES = \ + taler-exchange-kyc-trigger.c +taler_exchange_kyc_trigger_LDADD = \ + $(LIBGCRYPT_LIBS) \ + $(top_builddir)/src/lib/libtalerexchange.la \ + $(top_builddir)/src/util/libtalerutil.la \ + -lgnunetjson \ + -lgnunetcurl \ + -ljansson \ + -lgnunetutil \ + $(XLIB) + taler_auditor_offline_SOURCES = \ taler-auditor-offline.c taler_auditor_offline_LDADD = \ diff --git a/src/exchange-tools/taler-auditor-offline.c b/src/exchange-tools/taler-auditor-offline.c index 8c280d46b..2eb4596b8 100644 --- a/src/exchange-tools/taler-auditor-offline.c +++ b/src/exchange-tools/taler-auditor-offline.c @@ -1470,10 +1470,6 @@ main (int argc, }; enum GNUNET_GenericReturnValue ret; - if (GNUNET_OK != - GNUNET_STRINGS_get_utf8_args (argc, argv, - &argc, &argv)) - return EXIT_INVALIDARGUMENT; /* force linker to link against libtalerutil; if we do not do this, the linker may "optimize" libtalerutil away and skip #TALER_OS_init(), which we do need */ @@ -1484,7 +1480,6 @@ main (int argc, gettext_noop ("Operations for offline signing for a Taler exchange"), options, &run, NULL); - GNUNET_free_nz ((void *) argv); if (GNUNET_SYSERR == ret) return EXIT_INVALIDARGUMENT; if (GNUNET_NO == ret) diff --git a/src/exchange-tools/taler-exchange-dbinit.c b/src/exchange-tools/taler-exchange-dbinit.c index 7eb021a91..5fb587feb 100644 --- a/src/exchange-tools/taler-exchange-dbinit.c +++ b/src/exchange-tools/taler-exchange-dbinit.c @@ -195,10 +195,6 @@ main (int argc, }; enum GNUNET_GenericReturnValue ret; - if (GNUNET_OK != - GNUNET_STRINGS_get_utf8_args (argc, argv, - &argc, &argv)) - return EXIT_INVALIDARGUMENT; /* force linker to link against libtalerutil; if we do not do this, the linker may "optimize" libtalerutil away and skip #TALER_OS_init(), which we do need */ @@ -209,7 +205,6 @@ main (int argc, gettext_noop ("Initialize Taler exchange database"), options, &run, NULL); - GNUNET_free_nz ((void *) argv); if (GNUNET_SYSERR == ret) return EXIT_INVALIDARGUMENT; if (GNUNET_NO == ret) diff --git a/src/exchange-tools/taler-exchange-kyc-trigger.c b/src/exchange-tools/taler-exchange-kyc-trigger.c new file mode 100644 index 000000000..db3455c43 --- /dev/null +++ b/src/exchange-tools/taler-exchange-kyc-trigger.c @@ -0,0 +1,323 @@ +/* + This file is part of TALER + Copyright (C) 2020-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 taler-exchange-kyc-trigger.c + * @brief Support for manually triggering KYC/AML processes for testing + * @author Christian Grothoff + */ +#include <platform.h> +#include <gnunet/gnunet_json_lib.h> +#include <gnunet/gnunet_util_lib.h> +#include "taler_json_lib.h" +#include "taler_exchange_service.h" + + +/** + * Our private key. + */ +static struct TALER_ReservePrivateKeyP reserve_priv; + +/** + * Our public key. + */ +static struct TALER_ReservePublicKeyP reserve_pub; + +/** + * Our context for making HTTP requests. + */ +static struct GNUNET_CURL_Context *ctx; + +/** + * Reschedule context for #ctx. + */ +static struct GNUNET_CURL_RescheduleContext *rc; + +/** + * Handle to the exchange's configuration + */ +static const struct GNUNET_CONFIGURATION_Handle *kcfg; + +/** + * Handle for exchange interaction. + */ +static struct TALER_EXCHANGE_KycWalletHandle *kwh; + +/** + * Balance threshold to report to the exchange. + */ +static struct TALER_Amount balance; + +/** + * Return value from main(). + */ +static int global_ret; + +/** + * Currency we have configured. + */ +static char *currency; + +/** + * URL of the exchange we are interacting with + * as per our configuration. + */ +static char *CFG_exchange_url; + + +/** + * Function called with the result for a wallet looking + * up its KYC payment target. + * + * @param cls closure + * @param ks the wallets KYC payment target details + */ +static void +kyc_wallet_cb ( + void *cls, + const struct TALER_EXCHANGE_WalletKycResponse *ks) +{ + kwh = NULL; + switch (ks->hr.http_status) + { + case MHD_HTTP_OK: + fprintf (stdout, + "OK, next treshold at %s\n", + TALER_amount2s (&ks->details.ok.next_threshold)); + break; + case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS: + { + const struct TALER_EXCHANGE_KycNeededRedirect *knr + = &ks->details.unavailable_for_legal_reasons; + char *ps; + + ps = GNUNET_STRINGS_data_to_string_alloc (&knr->h_payto, + sizeof (knr->h_payto)); + fprintf (stderr, + "KYC needed (%llu, %s) for %s\n", + (unsigned long long) knr->requirement_row, + knr->bad_kyc_auth + ? "KYC auth needed" + : "KYC auth OK", + ps); + GNUNET_free (ps); + } + break; + default: + fprintf (stdout, + "Unexpected HTTP status %u\n", + ks->hr.http_status); + break; + } + GNUNET_SCHEDULER_shutdown (); +} + + +/** + * Shutdown task. Invoked when the application is being terminated. + * + * @param cls NULL + */ +static void +do_shutdown (void *cls) +{ + (void) cls; + if (NULL != kwh) + { + TALER_EXCHANGE_kyc_wallet_cancel (kwh); + kwh = NULL; + } + if (NULL != ctx) + { + GNUNET_CURL_fini (ctx); + ctx = NULL; + } + if (NULL != rc) + { + GNUNET_CURL_gnunet_rc_destroy (rc); + rc = NULL; + } +} + + +/** + * Load the reserve key. + * + * @param do_create #GNUNET_YES if the key may be created + * @return #GNUNET_OK on success + */ +static enum GNUNET_GenericReturnValue +load_reserve_key (int do_create) +{ + char *fn; + + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_filename (kcfg, + "exchange-testing", + "RESERVE_PRIV_FILE", + &fn)) + { + enum GNUNET_GenericReturnValue ret; + + if (GNUNET_YES != + GNUNET_DISK_file_test (fn)) + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Account private key `%s' does not exist yet, creating it!\n", + fn); + ret = GNUNET_CRYPTO_eddsa_key_from_file (fn, + do_create, + &reserve_priv.eddsa_priv); + if (GNUNET_SYSERR == ret) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to initialize master key from file `%s': %s\n", + fn, + "could not create file"); + GNUNET_free (fn); + return GNUNET_SYSERR; + } + GNUNET_free (fn); + } + else + { + GNUNET_CRYPTO_eddsa_key_create (&reserve_priv.eddsa_priv); + } + GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv.eddsa_priv, + &reserve_pub.eddsa_pub); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Using reserve public key %s\n", + TALER_B2S (&reserve_pub)); + return GNUNET_OK; +} + + +/** + * Main function that will be run. + * + * @param cls closure + * @param args remaining command-line arguments + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param cfg configuration + */ +static void +run (void *cls, + char *const *args, + const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + (void) cls; + (void) cfgfile; + kcfg = cfg; + + if (GNUNET_OK != + load_reserve_key (GNUNET_YES)) + { + GNUNET_break (0); + global_ret = EXIT_FAILURE; + return; + } + if (GNUNET_OK != + TALER_config_get_currency (kcfg, + ¤cy)) + { + global_ret = EXIT_NOTCONFIGURED; + return; + } + if ( (GNUNET_OK != + TALER_amount_is_valid (&balance)) || + (0 != strcmp (balance.currency, + currency)) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Invalid balance threshold `%s'\n", + TALER_amount2s (&balance)); + global_ret = EXIT_FAILURE; + return; + } + if ( (NULL == CFG_exchange_url) && + (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (kcfg, + "exchange", + "BASE_URL", + &CFG_exchange_url)) ) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "exchange", + "BASE_URL"); + global_ret = EXIT_NOTCONFIGURED; + GNUNET_SCHEDULER_shutdown (); + return; + } + ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule, + &rc); + rc = GNUNET_CURL_gnunet_rc_create (ctx); + GNUNET_SCHEDULER_add_shutdown (&do_shutdown, + NULL); + kwh = TALER_EXCHANGE_kyc_wallet (ctx, + CFG_exchange_url, + &reserve_priv, + &balance, + &kyc_wallet_cb, + NULL); + if (NULL == kwh) + { + GNUNET_break (0); + GNUNET_SCHEDULER_shutdown (); + } +} + + +/** + * The main function of the taler-exchange-kyc-trigger tool. + * + * @param argc number of arguments from the command line + * @param argv command line arguments + * @return 0 ok, 1 on error + */ +int +main (int argc, + char *const *argv) +{ + struct GNUNET_GETOPT_CommandLineOption options[] = { + TALER_getopt_get_amount ('b', + "balance", + "AMOUNT", + "balance threshold to report to the exchange", + &balance), + GNUNET_GETOPT_OPTION_END + }; + enum GNUNET_GenericReturnValue ret; + + /* force linker to link against libtalerutil; if we do + not do this, the linker may "optimize" libtalerutil + away and skip #TALER_OS_init(), which we do need */ + (void) TALER_project_data_default (); + TALER_OS_init (); + ret = GNUNET_PROGRAM_run ( + argc, argv, + "taler-exchange-kyc-trigger", + gettext_noop ( + "Trigger KYC/AML measures based on high wallet balance for testing"), + options, + &run, NULL); + if (GNUNET_SYSERR == ret) + return EXIT_INVALIDARGUMENT; + if (GNUNET_NO == ret) + return EXIT_SUCCESS; + return global_ret; +} + + +/* end of taler-exchange-kyc-trigger.c */ diff --git a/src/exchange-tools/taler-exchange-offline.c b/src/exchange-tools/taler-exchange-offline.c index 1f10c55e3..76d5ba3cc 100644 --- a/src/exchange-tools/taler-exchange-offline.c +++ b/src/exchange-tools/taler-exchange-offline.c @@ -130,7 +130,7 @@ static struct TALER_MasterPrivateKeyP master_priv; /** - * Our private key, initialized in #load_offline_key(). + * Our public key, initialized in #load_offline_key(). */ static struct TALER_MasterPublicKeyP master_pub; @@ -576,7 +576,6 @@ static struct GNUNET_SCHEDULER_Task *nxt; */ static struct TALER_EXCHANGE_ManagementGetKeysHandle *mgkh; - /** * Active AML staff change requests. */ @@ -2160,7 +2159,7 @@ upload_keys (const char *exchange_url, struct TALER_EXCHANGE_SigningKeySignature *ss = &pkd.sign_sigs[i]; json_t *val = json_array_get (signkey_sigs, i); - struct GNUNET_JSON_Specification spec[] = { + struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_fixed_auto ("exchange_pub", &ss->exchange_pub), GNUNET_JSON_spec_fixed_auto ("master_sig", @@ -2170,7 +2169,7 @@ upload_keys (const char *exchange_url, if (GNUNET_OK != GNUNET_JSON_parse (val, - spec, + ispec, &err_name, &err_line)) { @@ -2190,7 +2189,7 @@ upload_keys (const char *exchange_url, struct TALER_EXCHANGE_DenominationKeySignature *ds = &pkd.denom_sigs[i]; json_t *val = json_array_get (denom_sigs, i); - struct GNUNET_JSON_Specification spec[] = { + struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_fixed_auto ("h_denom_pub", &ds->h_denom_pub), GNUNET_JSON_spec_fixed_auto ("master_sig", @@ -2200,7 +2199,7 @@ upload_keys (const char *exchange_url, if (GNUNET_OK != GNUNET_JSON_parse (val, - spec, + ispec, &err_name, &err_line)) { @@ -3314,7 +3313,8 @@ do_del_wire (char *const *args) if (NULL != in) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Downloaded data was not consumed, not deleting wire account\n"); + "Downloaded data was not consumed, not deleting wire account\n") + ; GNUNET_SCHEDULER_shutdown (); global_ret = EXIT_FAILURE; return; @@ -5474,10 +5474,6 @@ main (int argc, not do this, the linker may "optimize" libtalerutil away and skip #TALER_OS_init(), which we do need */ (void) TALER_project_data_default (); - if (GNUNET_OK != - GNUNET_STRINGS_get_utf8_args (argc, argv, - &argc, &argv)) - return EXIT_INVALIDARGUMENT; TALER_OS_init (); ret = GNUNET_PROGRAM_run ( argc, argv, @@ -5485,7 +5481,6 @@ main (int argc, gettext_noop ("Operations for offline signing for a Taler exchange"), options, &run, NULL); - GNUNET_free_nz ((void *) argv); if (GNUNET_SYSERR == ret) return EXIT_INVALIDARGUMENT; if (GNUNET_NO == ret) diff --git a/src/exchange/taler-exchange-aggregator.c b/src/exchange/taler-exchange-aggregator.c index ae77cb6c3..764c79844 100644 --- a/src/exchange/taler-exchange-aggregator.c +++ b/src/exchange/taler-exchange-aggregator.c @@ -111,6 +111,12 @@ struct AggregationUnit */ bool have_transient; + /** + * Is the wrong merchant public key associated with + * the KYC data? + */ + bool bad_kyc_auth; + }; @@ -507,13 +513,26 @@ legitimization_satisfied (struct AggregationUnit *au_active) json_t *jrule; if (kyc_off) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "KYC checks are off, legitimization satisfied\n"); return true; + } { json_t *jrules; + union TALER_AccountPublicKeyP account_pub; + struct TALER_ReservePublicKeyP reserve_pub; + bool no_account_pub; + bool no_reserve_pub; + /* FIXME: optimization potential: custom API to *just* get jrules... */ qs = db_plugin->get_kyc_rules (db_plugin->cls, &au_active->h_payto, + &no_account_pub, + &account_pub, + &no_reserve_pub, + &reserve_pub, &jrules); if (qs < 0) { @@ -560,9 +579,11 @@ legitimization_satisfied (struct AggregationUnit *au_active) au_active->payto_uri, &au_active->h_payto, NULL, + &au_active->merchant_pub, jrule, TALER_KYCLOGIC_rule2priority (requirement), - &au_active->requirement_row); + &au_active->requirement_row, + &au_active->bad_kyc_auth); json_decref (jrule); if (qs < 0) { @@ -1288,10 +1309,6 @@ main (int argc, }; enum GNUNET_GenericReturnValue ret; - if (GNUNET_OK != - GNUNET_STRINGS_get_utf8_args (argc, argv, - &argc, &argv)) - return EXIT_INVALIDARGUMENT; TALER_OS_init (); ret = GNUNET_PROGRAM_run ( argc, argv, @@ -1300,7 +1317,6 @@ main (int argc, "background process that aggregates and executes wire transfers"), options, &run, NULL); - GNUNET_free_nz ((void *) argv); if (GNUNET_SYSERR == ret) return EXIT_INVALIDARGUMENT; if (GNUNET_NO == ret) diff --git a/src/exchange/taler-exchange-closer.c b/src/exchange/taler-exchange-closer.c index 779525c4e..95d0b7083 100644 --- a/src/exchange/taler-exchange-closer.c +++ b/src/exchange/taler-exchange-closer.c @@ -224,7 +224,6 @@ expired_reserve_cb (void *cls, struct TALER_Amount closing_fee; struct TALER_WireFeeSet fees; enum TALER_AmountArithmeticResult ret; - enum GNUNET_DB_QueryStatus qs; const struct TALER_EXCHANGEDB_AccountInfo *wa; (void) cls; @@ -316,30 +315,37 @@ expired_reserve_cb (void *cls, reserve_pub, GNUNET_MIN (sizeof (wtid), sizeof (*reserve_pub))); - qs = db_plugin->insert_reserve_closed (db_plugin->cls, - reserve_pub, - now, - account_payto_uri, - &wtid, - left, - &closing_fee, - close_request_row); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Closing reserve %s over %s (%d, %d)\n", - TALER_B2S (reserve_pub), - TALER_amount2s (left), - (int) ret, - qs); - /* Check for hard failure */ - if (GNUNET_DB_STATUS_HARD_ERROR == qs) + { - GNUNET_break (0); - global_ret = EXIT_FAILURE; - GNUNET_SCHEDULER_shutdown (); - return GNUNET_SYSERR; + enum GNUNET_DB_QueryStatus qs; + + qs = db_plugin->insert_reserve_closed (db_plugin->cls, + reserve_pub, + now, + account_payto_uri, + &wtid, + left, + &closing_fee, + close_request_row); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Closing reserve %s over %s (%d, %d)\n", + TALER_B2S (reserve_pub), + TALER_amount2s (left), + (int) ret, + qs); + /* Check for hard failure */ + if (GNUNET_DB_STATUS_HARD_ERROR == qs) + { + GNUNET_break (0); + global_ret = EXIT_FAILURE; + GNUNET_SCHEDULER_shutdown (); + return GNUNET_SYSERR; + } } if (TALER_amount_is_zero (&amount_without_fee)) { + enum GNUNET_DB_QueryStatus qs; + /* Reserve balance was zero OR soft error */ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Reserve was virtually empty, moving on\n"); @@ -361,6 +367,7 @@ expired_reserve_cb (void *cls, { void *buf; size_t buf_size; + enum GNUNET_DB_QueryStatus qs; TALER_BANK_prepare_transfer (account_payto_uri, &amount_without_fee, @@ -374,24 +381,24 @@ expired_reserve_cb (void *cls, buf, buf_size); GNUNET_free (buf); - } - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - global_ret = EXIT_FAILURE; - GNUNET_SCHEDULER_shutdown (); - return GNUNET_SYSERR; - case GNUNET_DB_STATUS_SOFT_ERROR: - /* start again */ - return GNUNET_NO; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - GNUNET_break (0); - global_ret = EXIT_FAILURE; - GNUNET_SCHEDULER_shutdown (); - return GNUNET_SYSERR; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - break; + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); + global_ret = EXIT_FAILURE; + GNUNET_SCHEDULER_shutdown (); + return GNUNET_SYSERR; + case GNUNET_DB_STATUS_SOFT_ERROR: + /* start again */ + return GNUNET_NO; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + GNUNET_break (0); + global_ret = EXIT_FAILURE; + GNUNET_SCHEDULER_shutdown (); + return GNUNET_SYSERR; + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + break; + } } return GNUNET_OK; } @@ -542,10 +549,6 @@ main (int argc, }; enum GNUNET_GenericReturnValue ret; - if (GNUNET_OK != - GNUNET_STRINGS_get_utf8_args (argc, argv, - &argc, &argv)) - return EXIT_INVALIDARGUMENT; TALER_OS_init (); ret = GNUNET_PROGRAM_run ( argc, argv, @@ -553,7 +556,6 @@ main (int argc, gettext_noop ("background process that closes expired reserves"), options, &run, NULL); - GNUNET_free_nz ((void *) argv); if (GNUNET_SYSERR == ret) return EXIT_INVALIDARGUMENT; if (GNUNET_NO == ret) diff --git a/src/exchange/taler-exchange-drain.c b/src/exchange/taler-exchange-drain.c index d409487c1..b8d655a93 100644 --- a/src/exchange/taler-exchange-drain.c +++ b/src/exchange/taler-exchange-drain.c @@ -407,10 +407,6 @@ main (int argc, }; enum GNUNET_GenericReturnValue ret; - if (GNUNET_OK != - GNUNET_STRINGS_get_utf8_args (argc, argv, - &argc, &argv)) - return EXIT_INVALIDARGUMENT; TALER_OS_init (); ret = GNUNET_PROGRAM_run ( argc, argv, @@ -419,7 +415,6 @@ main (int argc, "process that executes a single profit drain"), options, &run, NULL); - GNUNET_free_nz ((void *) argv); if (GNUNET_SYSERR == ret) return EXIT_INVALIDARGUMENT; if (GNUNET_NO == ret) diff --git a/src/exchange/taler-exchange-expire.c b/src/exchange/taler-exchange-expire.c index b2d34ee1c..22b3da622 100644 --- a/src/exchange/taler-exchange-expire.c +++ b/src/exchange/taler-exchange-expire.c @@ -476,10 +476,6 @@ main (int argc, }; enum GNUNET_GenericReturnValue ret; - if (GNUNET_OK != - GNUNET_STRINGS_get_utf8_args (argc, argv, - &argc, &argv)) - return EXIT_INVALIDARGUMENT; TALER_OS_init (); ret = GNUNET_PROGRAM_run ( argc, argv, @@ -488,7 +484,6 @@ main (int argc, "background process that expires purses"), options, &run, NULL); - GNUNET_free_nz ((void *) argv); if (GNUNET_SYSERR == ret) return EXIT_INVALIDARGUMENT; if (GNUNET_NO == ret) diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c index e047d8471..e93663357 100644 --- a/src/exchange/taler-exchange-httpd.c +++ b/src/exchange/taler-exchange-httpd.c @@ -53,6 +53,7 @@ #include "taler-exchange-httpd_kyc-upload.h" #include "taler-exchange-httpd_kyc-wallet.h" #include "taler-exchange-httpd_kyc-webhook.h" +#include "taler-exchange-httpd_aml-decision.h" #include "taler-exchange-httpd_link.h" #include "taler-exchange-httpd_management.h" #include "taler-exchange-httpd_melt.h" @@ -156,16 +157,6 @@ struct TALER_AttributeEncryptionKeyP TEH_attribute_key; struct TALER_EXCHANGEDB_Plugin *TEH_plugin; /** - * Maximum amount per individual transaction. Invalid amount if unlimited. - */ -struct TALER_Amount TEH_transaction_limit; - -/** - * Maximum amount per refund. Invalid amount if unlimited. - */ -struct TALER_Amount TEH_refund_limit; - -/** * Absolute STEFAN parameter. */ struct TALER_Amount TEH_stefan_abs; @@ -176,11 +167,33 @@ struct TALER_Amount TEH_stefan_abs; struct TALER_Amount TEH_stefan_log; /** + * Smallest amount that can be transferred. Used for the + * KYC auth transfers by default. + */ +struct TALER_Amount TEH_tiny_amount; + +/** * Linear STEFAN parameter. */ float TEH_stefan_lin; /** + * JSON array with hard limits for /keys response. + */ +json_t *TEH_hard_limits; + +/** + * JSON array with zero limits for /keys response. + */ +json_t *TEH_zero_limits; + +/** + * URL where users can discover shops accepting digital cash + * issued by this exchange. Can be NULL. + */ +char *TEH_shopping_url; + +/** * Where to redirect users from "/"? */ static char *toplevel_redirect_url; @@ -2096,7 +2109,7 @@ handle_mhd_request (void *cls, return ret; } return TEH_handler_kyc_upload (rc, - url + strlen ("/kyc-upload/"), + &url[strlen ("/kyc-upload/")], upload_data_size, upload_data); } @@ -2144,6 +2157,10 @@ exchange_serve_process_config (const char *cfg_fn) GNUNET_break (0); return GNUNET_SYSERR; } + TEH_hard_limits + = TALER_KYCLOGIC_get_hard_limits (); + TEH_zero_limits + = TALER_KYCLOGIC_get_zero_limits (); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (TEH_cfg, "exchange", @@ -2217,24 +2234,6 @@ exchange_serve_process_config (const char *cfg_fn) } /* currency parser must provide default spec for main currency */ GNUNET_assert (NULL != TEH_cspec); - if (GNUNET_SYSERR == - TALER_config_get_amount (TEH_cfg, - "exchange", - "TRANSACTION_LIMIT", - &TEH_transaction_limit)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - if (GNUNET_SYSERR == - TALER_config_get_amount (TEH_cfg, - "exchange", - "REFUND_LIMIT", - &TEH_refund_limit)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } GNUNET_assert (GNUNET_OK == TALER_amount_set_zero (TEH_currency, &TEH_stefan_abs)); @@ -2259,6 +2258,24 @@ exchange_serve_process_config (const char *cfg_fn) GNUNET_break (0); return GNUNET_SYSERR; } + GNUNET_assert (GNUNET_OK == + TALER_amount_set_zero (TEH_currency, + &TEH_tiny_amount)); + if ( (GNUNET_OK != + TALER_config_get_amount (TEH_cfg, + "exchange", + "TINY_AMOUNT", + &TEH_tiny_amount)) && + (GNUNET_OK != + TALER_config_get_amount (TEH_cfg, + "auditor", + "TINY_AMOUNT", + &TEH_tiny_amount)) ) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING, + "exchange", + "TINY_AMOUNT"); + } TEH_stefan_lin = 0.0f; if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_float (TEH_cfg, @@ -2281,7 +2298,8 @@ exchange_serve_process_config (const char *cfg_fn) "BASE_URL"); return GNUNET_SYSERR; } - if (! TALER_url_valid_charset (TEH_base_url)) + if ( (! TALER_url_valid_charset (TEH_base_url)) || + (! TALER_is_web_url (TEH_base_url) ) ) { GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "exchange", @@ -2289,6 +2307,25 @@ exchange_serve_process_config (const char *cfg_fn) "invalid URL"); return GNUNET_SYSERR; } + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (TEH_cfg, + "exchange", + "SHOPPING_URL", + &TEH_shopping_url)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING, + "exchange", + "SHOPPING_URL"); + } + if ( (NULL != TEH_shopping_url) && + (! TALER_is_web_url (TEH_shopping_url)) ) + { + GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, + "exchange", + "SHOPPING_URL", + "invalid URL"); + return GNUNET_SYSERR; + } { char *master_public_key_str; @@ -2601,11 +2638,14 @@ connection_done (void *cls, static void do_shutdown (void *cls) { - struct MHD_Daemon *mhd; + struct MHD_Daemon *my_mhd; (void) cls; - mhd = TALER_MHD_daemon_stop (); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Shutdown of taler-exchange-httpd\n"); + my_mhd = TALER_MHD_daemon_stop (); TEH_resume_keys_requests (true); + TEH_batch_deposit_cleanup (); TEH_age_withdraw_cleanup (); TEH_batch_withdraw_cleanup (); TEH_reserves_close_cleanup (); @@ -2619,11 +2659,13 @@ do_shutdown (void *cls) TEH_kyc_check_cleanup (); TEH_kyc_info_cleanup (); TEH_kyc_proof_cleanup (); + TEH_kyc_start_cleanup (); + TEH_aml_decision_cleanup (); TALER_KYCLOGIC_kyc_done (); - if (NULL != mhd) + if (NULL != my_mhd) { - MHD_stop_daemon (mhd); - mhd = NULL; + MHD_stop_daemon (my_mhd); + my_mhd = NULL; } TEH_wire_done (); TEH_extensions_done (); diff --git a/src/exchange/taler-exchange-httpd.h b/src/exchange/taler-exchange-httpd.h index 6f86fa39c..a5b597f31 100644 --- a/src/exchange/taler-exchange-httpd.h +++ b/src/exchange/taler-exchange-httpd.h @@ -98,14 +98,14 @@ extern struct TALER_AttributeEncryptionKeyP TEH_attribute_key; extern struct TALER_EXCHANGEDB_Plugin *TEH_plugin; /** - * Maximum amount per individual transaction. Invalid amount if unlimited. + * JSON array with hard limits for /keys response. */ -extern struct TALER_Amount TEH_transaction_limit; +extern json_t *TEH_hard_limits; /** - * Maximum amount per refund. Invalid amount if unlimited. + * JSON array with zero limits for /keys response. */ -extern struct TALER_Amount TEH_refund_limit; +extern json_t *TEH_zero_limits; /** * Absolute STEFAN parameter. @@ -118,6 +118,18 @@ extern struct TALER_Amount TEH_stefan_abs; extern struct TALER_Amount TEH_stefan_log; /** + * Smallest amount that can be transferred. Used for the + * KYC auth transfers by default. + */ +extern struct TALER_Amount TEH_tiny_amount; + +/** + * URL where users can discover shops accepting digital cash + * issued by this exchange. Can be NULL. + */ +extern char *TEH_shopping_url; + +/** * Linear STEFAN parameter. */ extern float TEH_stefan_lin; diff --git a/src/exchange/taler-exchange-httpd_age-withdraw.c b/src/exchange/taler-exchange-httpd_age-withdraw.c index ce1ea951d..e7d4b139c 100644 --- a/src/exchange/taler-exchange-httpd_age-withdraw.c +++ b/src/exchange/taler-exchange-httpd_age-withdraw.c @@ -499,7 +499,8 @@ check_kyc_result (struct AgeWithdrawContext *awc) TEH_RESPONSE_reply_kyc_required ( awc->rc->connection, &awc->h_payto, - &awc->kyc)); + &awc->kyc, + false)); return; } awc->phase++; @@ -630,7 +631,7 @@ run_legi_check (struct AgeWithdrawContext *awc) TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW, payto_uri, &awc->h_payto, - NULL, + NULL, /* no account pub: this is about the origin account */ &withdraw_amount_cb, awc, &withdraw_legi_cb, @@ -966,6 +967,8 @@ TEH_handler_age_withdraw ( size_t num_coins = json_array_size (j_denom_hs); const char *error = NULL; + _Static_assert ((TALER_MAX_FRESH_COINS < INT_MAX / TALER_CNC_KAPPA), + "TALER_MAX_FRESH_COINS too large"); if (0 == num_coins) error = "denoms_h must not be empty"; else if (num_coins != json_array_size (j_blinded_coin_evs)) @@ -979,9 +982,6 @@ TEH_handler_age_withdraw ( error = "maximum number of coins that can be withdrawn has been exceeded"; - _Static_assert ((TALER_MAX_FRESH_COINS < INT_MAX / TALER_CNC_KAPPA), - "TALER_MAX_FRESH_COINS too large"); - if (NULL != error) { GNUNET_break_op (0); diff --git a/src/exchange/taler-exchange-httpd_aml-attributes-get.c b/src/exchange/taler-exchange-httpd_aml-attributes-get.c index 1bf7888fe..ee3b6de5a 100644 --- a/src/exchange/taler-exchange-httpd_aml-attributes-get.c +++ b/src/exchange/taler-exchange-httpd_aml-attributes-get.c @@ -41,7 +41,6 @@ * * @param cls closure * @param row_id current row in kyc_attributes table - * @param provider_name which provider collected the data, NULL for user upload * @param collection_time when were the attributes collected * @param enc_attributes_size length of @a enc_attributes * @param enc_attributes the encrypted collected attributes @@ -50,7 +49,6 @@ static void detail_cb ( void *cls, uint64_t row_id, - const char *provider_name, struct GNUNET_TIME_Timestamp collection_time, size_t enc_attributes_size, const void *enc_attributes) @@ -74,9 +72,6 @@ detail_cb ( GNUNET_JSON_pack_int64 ("rowid", row_id), GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_string ("provider_name", - provider_name)), - GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_object_steal ("attributes", attrs)), GNUNET_JSON_pack_timestamp ("collection_time", diff --git a/src/exchange/taler-exchange-httpd_aml-decision.c b/src/exchange/taler-exchange-httpd_aml-decision.c index 5eeec080f..1096bb7dd 100644 --- a/src/exchange/taler-exchange-httpd_aml-decision.c +++ b/src/exchange/taler-exchange-httpd_aml-decision.c @@ -17,6 +17,7 @@ * @file taler-exchange-httpd_aml-decision.c * @brief Handle POST request about an AML decision. * @author Christian Grothoff + * @author Florian Dold */ #include "platform.h" #include <gnunet/gnunet_util_lib.h> @@ -28,7 +29,125 @@ #include "taler_mhd_lib.h" #include "taler_kyclogic_lib.h" #include "taler_signatures.h" +#include "taler-exchange-httpd_common_kyc.h" #include "taler-exchange-httpd_responses.h" +#include "taler-exchange-httpd_aml-decision.h" + + +/** + * Context used for processing the AML decision request. + */ +struct AmlDecisionContext +{ + + /** + * Kept in a DLL. + */ + struct AmlDecisionContext *next; + + /** + * Kept in a DLL. + */ + struct AmlDecisionContext *prev; + + /** + * HTTP status code to use with @e response. + */ + unsigned int response_code; + + /** + * Response to return, NULL if none yet. + */ + struct MHD_Response *response; + + /** + * Request we are processing. + */ + struct TEH_RequestContext *rc; + + /** + * Handle for async KYC processing. + */ + struct TEH_KycAmlTrigger *kat; + +}; + +/** + * Kept in a DLL. + */ +static struct AmlDecisionContext *adc_head; + +/** + * Kept in a DLL. + */ +static struct AmlDecisionContext *adc_tail; + + +void +TEH_aml_decision_cleanup () +{ + struct AmlDecisionContext *adc; + + while (NULL != (adc = adc_head)) + { + MHD_resume_connection (adc->rc->connection); + GNUNET_CONTAINER_DLL_remove (adc_head, + adc_tail, + adc); + } +} + + +/** + * Function called to clean up aml decision context. + * + * @param[in,out] rc context to clean up + */ +static void +aml_decision_cleaner (struct TEH_RequestContext *rc) +{ + struct AmlDecisionContext *adc = rc->rh_ctx; + + if (NULL != adc->kat) + { + TEH_kyc_finished_cancel (adc->kat); + adc->kat = NULL; + } + if (NULL != adc->response) + { + MHD_destroy_response (adc->response); + adc->response = NULL; + } + GNUNET_free (adc); +} + + +/** + * Function called after the KYC-AML trigger is done. + * + * @param cls closure + * @param http_status final HTTP status to return + * @param[in] response final HTTP ro return + */ +static void +aml_trigger_callback ( + void *cls, + unsigned int http_status, + struct MHD_Response *response) +{ + struct AmlDecisionContext *adc = cls; + + adc->kat = NULL; + GNUNET_assert (NULL == adc->response); + GNUNET_assert (NULL != response); + adc->response_code = http_status; + adc->response = response; + MHD_resume_connection (adc->rc->connection); + GNUNET_CONTAINER_DLL_remove (adc_head, + adc_tail, + adc); + TALER_MHD_daemon_trigger (); +} MHD_RESULT @@ -38,22 +157,30 @@ TEH_handler_post_aml_decision ( const json_t *root) { struct MHD_Connection *connection = rc->connection; + struct AmlDecisionContext *adc = rc->rh_ctx; const char *justification; - const char *new_measure = NULL; + const char *new_measures = NULL; bool to_investigate; struct GNUNET_TIME_Timestamp decision_time; const json_t *new_rules; const json_t *properties = NULL; + const char *payto_uri = NULL; struct TALER_PaytoHashP h_payto; struct TALER_AmlOfficerSignatureP officer_sig; + struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs = NULL; + MHD_RESULT ret; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_string ( - "new_measure", - &new_measure), + "new_measures", + &new_measures), NULL), GNUNET_JSON_spec_string ("justification", &justification), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("payto_uri", + &payto_uri), + NULL), GNUNET_JSON_spec_fixed_auto ("h_payto", &h_payto), GNUNET_JSON_spec_object_const ("new_rules", @@ -73,6 +200,23 @@ TEH_handler_post_aml_decision ( struct GNUNET_TIME_Timestamp expiration_time; json_t *jmeasures = NULL; + if (NULL == adc) + { + /* Initialize context */ + adc = GNUNET_new (struct AmlDecisionContext); + adc->rc = rc; + rc->rh_ctx = adc; + rc->rh_cleaner = aml_decision_cleaner; + } + + if (NULL != adc->response) + { + ret = MHD_queue_response (rc->connection, + adc->response_code, + adc->response); + goto done; + } + { enum GNUNET_GenericReturnValue res; @@ -80,13 +224,37 @@ TEH_handler_post_aml_decision ( root, spec); if (GNUNET_SYSERR == res) - return MHD_NO; /* hard failure */ + { + ret = MHD_NO; /* hard failure */ + goto done; + } if (GNUNET_NO == res) { GNUNET_break_op (0); - return MHD_YES; /* failure */ + ret = MHD_YES /* failure */; + goto done; } } + if (NULL != payto_uri) + { + struct TALER_PaytoHashP h_payto2; + + TALER_payto_hash (payto_uri, + &h_payto2); + if (0 != + GNUNET_memcmp (&h_payto, + &h_payto2)) + { + GNUNET_break (0); + ret = TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + "payto_uri"); + goto done; + } + } + TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++; if (GNUNET_OK != TALER_officer_aml_decision_verify ( @@ -95,50 +263,50 @@ TEH_handler_post_aml_decision ( &h_payto, new_rules, properties, - new_measure, + new_measures, to_investigate, officer_pub, &officer_sig)) { GNUNET_break_op (0); - return TALER_MHD_reply_with_error ( + ret = TALER_MHD_reply_with_error ( connection, MHD_HTTP_FORBIDDEN, TALER_EC_EXCHANGE_AML_DECISION_ADD_SIGNATURE_INVALID, NULL); + goto done; } + lrs = TALER_KYCLOGIC_rules_parse (new_rules); + if (NULL == lrs) { - struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs; + GNUNET_break_op (0); + ret = TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + "legitimization rule malformed"); + goto done; + } - lrs = TALER_KYCLOGIC_rules_parse (new_rules); - if (NULL == lrs) + expiration_time = TALER_KYCLOGIC_rules_get_expiration (lrs); + if (NULL != new_measures) + { + jmeasures + = TALER_KYCLOGIC_get_measures (lrs, + new_measures); + if (NULL == jmeasures) { GNUNET_break_op (0); - return TALER_MHD_reply_with_error ( + /* Request specified a new_measure for which the given + rule set does not work as it does not define the measure */ + ret = TALER_MHD_reply_with_error ( connection, MHD_HTTP_BAD_REQUEST, TALER_EC_GENERIC_PARAMETER_MALFORMED, - "legitimization rule malformed"); - } - expiration_time = TALER_KYCLOGIC_rules_get_expiration (lrs); - if (NULL != new_measure) - { - jmeasures = TALER_KYCLOGIC_get_measure (lrs, - new_measure); - if (NULL == jmeasures) - { - GNUNET_break_op (0); - /* Request specified a new_measure for which the given - rule set does not work as it does not define the measure */ - return TALER_MHD_reply_with_error ( - connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "new_measure/new_rules"); - } + "new_measures/new_rules"); + goto done; } - TALER_KYCLOGIC_rules_free (lrs); } { @@ -147,14 +315,17 @@ TEH_handler_post_aml_decision ( bool invalid_officer = true; bool unknown_account = false; + /* We keep 'new_measures' around mostly so that + the auditor can later verify officer_sig */ qs = TEH_plugin->insert_aml_decision (TEH_plugin->cls, + payto_uri, &h_payto, decision_time, expiration_time, properties, new_rules, to_investigate, - new_measure, + new_measures, jmeasures, justification, officer_pub, @@ -166,50 +337,118 @@ TEH_handler_post_aml_decision ( if (qs <= 0) { GNUNET_break (0); - return TALER_MHD_reply_with_error ( + ret = TALER_MHD_reply_with_error ( connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_GENERIC_DB_STORE_FAILED, "insert_aml_decision"); + goto done; } if (invalid_officer) { GNUNET_break_op (0); - return TALER_MHD_reply_with_error ( + ret = TALER_MHD_reply_with_error ( connection, MHD_HTTP_FORBIDDEN, TALER_EC_EXCHANGE_AML_DECISION_INVALID_OFFICER, NULL); + goto done; } if (unknown_account) { GNUNET_break_op (0); - return TALER_MHD_reply_with_error ( + ret = TALER_MHD_reply_with_error ( connection, MHD_HTTP_NOT_FOUND, TALER_EC_EXCHANGE_GENERIC_BANK_ACCOUNT_UNKNOWN, "h_payto"); + goto done; } if (GNUNET_TIME_timestamp_cmp (last_date, >=, decision_time)) { GNUNET_break_op (0); - return TALER_MHD_reply_with_error ( + ret = TALER_MHD_reply_with_error ( connection, MHD_HTTP_CONFLICT, TALER_EC_EXCHANGE_AML_DECISION_MORE_RECENT_PRESENT, NULL); + goto done; + } + } + /* Run instant measure if necessary */ + { + const struct TALER_KYCLOGIC_Measure *instant_ms = NULL; + struct MHD_Response *empty_response; + + if (NULL != new_measures) + { + instant_ms = TALER_KYCLOGIC_get_instant_measure (lrs, new_measures); } + if (NULL != instant_ms) + { + /* We have an 'instant' measure which means we must run the + AML program immediately instead of waiting for the account owner + to select some measure and contribute their KYC data. */ + json_t *attributes + = json_object (); /* instant: empty attributes */ + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Running instant measure after AML decision\n"); + GNUNET_assert (NULL != attributes); + empty_response + = MHD_create_response_from_buffer_static (0, + ""); + GNUNET_assert (NULL != empty_response); + adc->kat + = TEH_kyc_finished2 ( + &rc->async_scope_id, + 0LL, + instant_ms, + &h_payto, + "SKIP", /* provider */ + NULL, + NULL, + GNUNET_TIME_UNIT_FOREVER_ABS, + attributes, + MHD_HTTP_NO_CONTENT, /* http status */ + empty_response, /* MHD_Response */ + &aml_trigger_callback, + adc); + json_decref (attributes); + if (NULL == adc->kat) + { + GNUNET_break (0); + ret = TALER_MHD_reply_with_error ( + rc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_EXCHANGE_KYC_GENERIC_AML_LOGIC_BUG, + "TEH_kyc_finished"); + goto done; + } + + MHD_suspend_connection (adc->rc->connection); + GNUNET_CONTAINER_DLL_insert (adc_head, + adc_tail, + adc); + ret = MHD_YES; + goto done; + } } - return TALER_MHD_reply_static ( + ret = TALER_MHD_reply_static ( connection, MHD_HTTP_NO_CONTENT, NULL, NULL, 0); + goto done; + +done: + TALER_KYCLOGIC_rules_free (lrs); + return ret; } diff --git a/src/exchange/taler-exchange-httpd_aml-decision.h b/src/exchange/taler-exchange-httpd_aml-decision.h index 10056116d..316b9dda5 100644 --- a/src/exchange/taler-exchange-httpd_aml-decision.h +++ b/src/exchange/taler-exchange-httpd_aml-decision.h @@ -58,5 +58,10 @@ TEH_handler_aml_decisions_get ( const struct TALER_AmlOfficerPublicKeyP *officer_pub, const char *const args[]); +/** + * Clean up running POST /aml/$OFFICER_PUB/decisions requests. + */ +void +TEH_aml_decision_cleanup (void); #endif diff --git a/src/exchange/taler-exchange-httpd_batch-deposit.c b/src/exchange/taler-exchange-httpd_batch-deposit.c index 84f27dd94..fdb705e14 100644 --- a/src/exchange/taler-exchange-httpd_batch-deposit.c +++ b/src/exchange/taler-exchange-httpd_batch-deposit.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2023 Taler Systems SA + Copyright (C) 2014-2024 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -31,6 +31,7 @@ #include "taler_extensions_policy.h" #include "taler_json_lib.h" #include "taler_mhd_lib.h" +#include "taler-exchange-httpd_common_kyc.h" #include "taler-exchange-httpd_batch-deposit.h" #include "taler-exchange-httpd_responses.h" #include "taler_exchangedb_lib.h" @@ -44,34 +45,34 @@ struct BatchDepositContext { /** - * Array with the individual coin deposit fees. + * Kept in a DLL. */ - struct TALER_Amount *deposit_fees; + struct BatchDepositContext *next; /** - * Our timestamp (when we received the request). - * Possibly updated by the transaction if the - * request is idempotent (was repeated). + * Kept in a DLL. */ - struct GNUNET_TIME_Timestamp exchange_timestamp; + struct BatchDepositContext *prev; /** - * Details about the batch deposit operation. + * The request we are working on. */ - struct TALER_EXCHANGEDB_BatchDeposit bd; + struct TEH_RequestContext *rc; + /** + * Handle for the legitimization check. + */ + struct TEH_LegitimizationCheckHandle *lch; /** - * Total amount that is accumulated with this deposit, - * without fee. + * Array with the individual coin deposit fees. */ - struct TALER_Amount accumulated_total_without_fee; + struct TALER_Amount *deposit_fees; /** - * True, if no policy was present in the request. Then - * @e policy_json is NULL and @e h_policy will be all zero. + * Information about deposited coins. */ - bool has_no_policy; + struct TALER_EXCHANGEDB_CoinDepositInformation *cdis; /** * Additional details for policy extension relevant for this @@ -79,12 +80,16 @@ struct BatchDepositContext */ json_t *policy_json; + /** - * If @e policy_json was present, the corresponding policy extension - * calculates these details. These will be persisted in the policy_details - * table. + * Response to return, if set. */ - struct TALER_PolicyDetails policy_details; + struct MHD_Response *response; + + /** + * KYC status of the reserve used for the operation. + */ + struct TALER_EXCHANGEDB_KycStatus kyc; /** * Hash over @e policy_details, might be all zero @@ -102,63 +107,167 @@ struct BatchDepositContext */ uint64_t policy_details_serial_id; + /** + * Our timestamp (when we received the request). + * Possibly updated by the transaction if the + * request is idempotent (was repeated). + */ + struct GNUNET_TIME_Timestamp exchange_timestamp; + + /** + * Total amount that is accumulated with this deposit, + * without fee. + */ + struct TALER_Amount accumulated_total_without_fee; + + /** + * Details about the batch deposit operation. + */ + struct TALER_EXCHANGEDB_BatchDeposit bd; + + /** + * If @e policy_json was present, the corresponding policy extension + * calculates these details. These will be persisted in the policy_details + * table. + */ + struct TALER_PolicyDetails policy_details; + + /** + * HTTP status to return with @e response, or 0. + */ + unsigned int http_status; + + /** + * Our current state in the state machine. + */ + enum + { + BDC_PHASE_INIT = 0, + BDC_PHASE_PARSE = 1, + BDC_PHASE_POLICY = 2, + BDC_PHASE_KYC = 3, + BDC_PHASE_TRANSACT = 4, + BDC_PHASE_REPLY_SUCCESS = 5, + BDC_PHASE_SUSPENDED, + BDC_PHASE_CHECK_KYC_RESULT, + BDC_PHASE_GENERATE_REPLY_FAILURE, + BDC_PHASE_RETURN_YES, + BDC_PHASE_RETURN_NO, + } phase; + + /** + * True, if no policy was present in the request. Then + * @e policy_json is NULL and @e h_policy will be all zero. + */ + bool has_no_policy; + + /** + * KYC failed because a KYC auth transfer is needed + * to establish the merchant_pub. + */ + bool bad_kyc_auth; }; /** + * Head of list of suspended batch deposit operations. + */ +static struct BatchDepositContext *bdc_head; + +/** + * Tail of list of suspended batch deposit operations. + */ +static struct BatchDepositContext *bdc_tail; + + +void +TEH_batch_deposit_cleanup () +{ + struct BatchDepositContext *bdc; + + while (NULL != (bdc = bdc_head)) + { + GNUNET_assert (BDC_PHASE_SUSPENDED == bdc->phase); + bdc->phase = BDC_PHASE_RETURN_NO; + MHD_resume_connection (bdc->rc->connection); + GNUNET_CONTAINER_DLL_remove (bdc_head, + bdc_tail, + bdc); + } +} + + +/** + * Terminate the main loop by returning the final + * result. + * + * @param[in,out] bdc context to update phase for + * @param mres MHD status to return + */ +static void +finish_loop (struct BatchDepositContext *bdc, + MHD_RESULT mres) +{ + bdc->phase = (MHD_YES == mres) + ? BDC_PHASE_RETURN_YES + : BDC_PHASE_RETURN_NO; +} + + +/** * Send confirmation of batch deposit success to client. This function will * create a signed message affirming the given information and return it to * the client. By this, the exchange affirms that the coins had sufficient * (residual) value for the specified transaction and that it will execute the * requested batch deposit operation with the given wiring details. * - * @param connection connection to the client - * @param dc information about the batch deposit - * @return MHD result code + * @param[in,out] bdc information about the batch deposit */ -static MHD_RESULT -reply_batch_deposit_success ( - struct MHD_Connection *connection, - const struct BatchDepositContext *dc) +static void +bdc_phase_reply_success ( + struct BatchDepositContext *bdc) { - const struct TALER_EXCHANGEDB_BatchDeposit *bd = &dc->bd; + const struct TALER_EXCHANGEDB_BatchDeposit *bd = &bdc->bd; const struct TALER_CoinSpendSignatureP *csigs[GNUNET_NZL (bd->num_cdis)]; enum TALER_ErrorCode ec; struct TALER_ExchangePublicKeyP pub; struct TALER_ExchangeSignatureP sig; - for (unsigned int i = 0; i<bd->num_cdis; i++) + for (unsigned int i = 0; i<bdc->bd.num_cdis; i++) csigs[i] = &bd->cdis[i].csig; if (TALER_EC_NONE != (ec = TALER_exchange_online_deposit_confirmation_sign ( &TEH_keys_exchange_sign_, &bd->h_contract_terms, - &dc->h_wire, - dc->has_no_policy ? NULL : &dc->h_policy, - dc->exchange_timestamp, + &bdc->h_wire, + bdc->has_no_policy ? NULL : &bdc->h_policy, + bdc->exchange_timestamp, bd->wire_deadline, bd->refund_deadline, - &dc->accumulated_total_without_fee, + &bdc->accumulated_total_without_fee, bd->num_cdis, csigs, - &dc->bd.merchant_pub, + &bdc->bd.merchant_pub, &pub, &sig))) { GNUNET_break (0); - return TALER_MHD_reply_with_ec (connection, - ec, - NULL); + finish_loop (bdc, + TALER_MHD_reply_with_ec (bdc->rc->connection, + ec, + NULL)); + return; } - return TALER_MHD_REPLY_JSON_PACK ( - connection, - MHD_HTTP_OK, - GNUNET_JSON_pack_timestamp ("exchange_timestamp", - dc->exchange_timestamp), - GNUNET_JSON_pack_data_auto ("exchange_pub", - &pub), - GNUNET_JSON_pack_data_auto ("exchange_sig", - &sig)); + finish_loop (bdc, + TALER_MHD_REPLY_JSON_PACK ( + bdc->rc->connection, + MHD_HTTP_OK, + GNUNET_JSON_pack_timestamp ("exchange_timestamp", + bdc->exchange_timestamp), + GNUNET_JSON_pack_data_auto ("exchange_pub", + &pub), + GNUNET_JSON_pack_data_auto ("exchange_sig", + &sig))); } @@ -180,8 +289,8 @@ batch_deposit_transaction (void *cls, struct MHD_Connection *connection, MHD_RESULT *mhd_ret) { - struct BatchDepositContext *dc = cls; - const struct TALER_EXCHANGEDB_BatchDeposit *bd = &dc->bd; + struct BatchDepositContext *bdc = cls; + const struct TALER_EXCHANGEDB_BatchDeposit *bd = &bdc->bd; enum GNUNET_DB_QueryStatus qs = GNUNET_DB_STATUS_HARD_ERROR; uint32_t bad_balance_coin_index = UINT32_MAX; bool balance_ok; @@ -189,26 +298,26 @@ batch_deposit_transaction (void *cls, /* If the deposit has a policy associated to it, persist it. This will * insert or update the record. */ - if (! dc->has_no_policy) + if (! bdc->has_no_policy) { qs = TEH_plugin->persist_policy_details ( TEH_plugin->cls, - &dc->policy_details, - &dc->bd.policy_details_serial_id, - &dc->accumulated_total_without_fee, - &dc->policy_details.fulfillment_state); + &bdc->policy_details, + &bdc->bd.policy_details_serial_id, + &bdc->accumulated_total_without_fee, + &bdc->policy_details.fulfillment_state); if (qs < 0) return qs; - dc->bd.policy_blocked = - dc->policy_details.fulfillment_state != TALER_PolicyFulfillmentSuccess; + bdc->bd.policy_blocked = + bdc->policy_details.fulfillment_state != TALER_PolicyFulfillmentSuccess; } /* FIXME: replace by batch insert! */ - for (unsigned int i = 0; i<bd->num_cdis; i++) + for (unsigned int i = 0; i<bdc->bd.num_cdis; i++) { const struct TALER_EXCHANGEDB_CoinDepositInformation *cdi - = &bd->cdis[i]; + = &bdc->cdis[i]; uint64_t known_coin_id; qs = TEH_make_coin_known (&cdi->coin, @@ -226,23 +335,24 @@ batch_deposit_transaction (void *cls, qs = TEH_plugin->do_deposit ( TEH_plugin->cls, bd, - &dc->exchange_timestamp, + &bdc->exchange_timestamp, &balance_ok, &bad_balance_coin_index, &in_conflict); - if (qs < 0) + if (qs <= 0) { if (GNUNET_DB_STATUS_SOFT_ERROR == qs) return qs; TALER_LOG_WARNING ( "Failed to store /batch-deposit information in database\n"); - *mhd_ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "batch-deposit"); + *mhd_ret = TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_STORE_FAILED, + "batch-deposit"); return qs; } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "do_deposit returned: %d / %s[%u] / %s\n", qs, balance_ok ? "balance ok" : "balance insufficient", @@ -261,10 +371,11 @@ batch_deposit_transaction (void *cls, { TALER_LOG_WARNING ( "Failed to retrieve conflicting contract details from database\n"); - *mhd_ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "batch-deposit"); + *mhd_ret = TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_STORE_FAILED, + "batch-deposit"); return qs; } @@ -277,16 +388,16 @@ batch_deposit_transaction (void *cls, } if (! balance_ok) { - GNUNET_assert (bad_balance_coin_index < bd->num_cdis); + GNUNET_assert (bad_balance_coin_index < bdc->bd.num_cdis); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "returning history of conflicting coin (%s)\n", - TALER_B2S (&bd->cdis[bad_balance_coin_index].coin.coin_pub)); + TALER_B2S (&bdc->cdis[bad_balance_coin_index].coin.coin_pub)); *mhd_ret = TEH_RESPONSE_reply_coin_insufficient_funds ( connection, TALER_EC_EXCHANGE_GENERIC_INSUFFICIENT_FUNDS, - &bd->cdis[bad_balance_coin_index].coin.denom_pub_hash, - &bd->cdis[bad_balance_coin_index].coin.coin_pub); + &bdc->cdis[bad_balance_coin_index].coin.denom_pub_hash, + &bdc->cdis[bad_balance_coin_index].coin.coin_pub); return GNUNET_DB_STATUS_HARD_ERROR; } TEH_METRICS_num_success[TEH_MT_SUCCESS_DEPOSIT]++; @@ -295,12 +406,276 @@ batch_deposit_transaction (void *cls, /** + * Run database transaction. + * + * @param[in,out] bdc request context + */ +static void +bdc_phase_transact (struct BatchDepositContext *bdc) +{ + MHD_RESULT mhd_ret; + + if (GNUNET_SYSERR == + TEH_plugin->preflight (TEH_plugin->cls)) + { + GNUNET_break (0); + finish_loop (bdc, + TALER_MHD_reply_with_error ( + bdc->rc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_START_FAILED, + "preflight failure")); + return; + } + + if (GNUNET_OK != + TEH_DB_run_transaction (bdc->rc->connection, + "execute batch deposit", + TEH_MT_REQUEST_BATCH_DEPOSIT, + &mhd_ret, + &batch_deposit_transaction, + bdc)) + { + finish_loop (bdc, + mhd_ret); + return; + } + bdc->phase++; +} + + +/** + * Check if the @a bdc is replayed and we already have an + * answer. If so, replay the existing answer and return the + * HTTP response. + * + * @param bdc parsed request data + * @return true if the request is idempotent with an existing request + * false if we did not find the request in the DB and did not set @a mret + */ +static bool +check_request_idempotent ( + struct BatchDepositContext *bdc) +{ + const struct TEH_RequestContext *rc = bdc->rc; + enum GNUNET_DB_QueryStatus qs; + bool is_idempotent; + + qs = TEH_plugin->do_check_deposit_idempotent ( + TEH_plugin->cls, + &bdc->bd, + &bdc->exchange_timestamp, + &is_idempotent); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + finish_loop (bdc, + TALER_MHD_reply_with_error ( + rc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_FETCH_FAILED, + "get_withdraw_info")); + return true; + } + if ( (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) || + (! is_idempotent) ) + return false; + bdc->phase = BDC_PHASE_REPLY_SUCCESS; + return true; +} + + +/** + * Check the KYC result. + * + * @param bdc storage for request processing + */ +static void +bdc_phase_check_kyc_result (struct BatchDepositContext *bdc) +{ + /* return final positive response */ + if ( (! bdc->kyc.ok) || + (bdc->bad_kyc_auth) ) + { + if (check_request_idempotent (bdc)) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Request is idempotent!\n"); + return; + } + /* KYC required */ + finish_loop (bdc, + TEH_RESPONSE_reply_kyc_required ( + bdc->rc->connection, + &bdc->bd.wire_target_h_payto, + &bdc->kyc, + bdc->bad_kyc_auth)); + return; + } + bdc->phase = BDC_PHASE_TRANSACT; +} + + +/** + * Function called with the result of a legitimization + * check. + * + * @param cls closure + * @param lcr legitimization check result + */ +static void +deposit_legi_cb ( + void *cls, + const struct TEH_LegitimizationCheckResult *lcr) +{ + struct BatchDepositContext *bdc = cls; + + bdc->lch = NULL; + GNUNET_assert (BDC_PHASE_SUSPENDED == + bdc->phase); + MHD_resume_connection (bdc->rc->connection); + GNUNET_CONTAINER_DLL_remove (bdc_head, + bdc_tail, + bdc); + TALER_MHD_daemon_trigger (); + if (NULL != lcr->response) + { + bdc->response = lcr->response; + bdc->http_status = lcr->http_status; + bdc->phase = BDC_PHASE_GENERATE_REPLY_FAILURE; + return; + } + bdc->kyc = lcr->kyc; + bdc->bad_kyc_auth = lcr->bad_kyc_auth; + bdc->phase = BDC_PHASE_CHECK_KYC_RESULT; +} + + +/** + * Function called to iterate over KYC-relevant transaction amounts for a + * particular time range. Called within a database transaction, so must + * not start a new one. + * + * @param cls closure, identifies the event type and account to iterate + * over events for + * @param limit maximum time-range for which events should be fetched + * (timestamp in the past) + * @param cb function to call on each event found, events must be returned + * in reverse chronological order + * @param cb_cls closure for @a cb, of type struct AgeWithdrawContext + * @return transaction status + */ +static enum GNUNET_DB_QueryStatus +deposit_amount_cb ( + void *cls, + struct GNUNET_TIME_Absolute limit, + TALER_EXCHANGEDB_KycAmountCallback cb, + void *cb_cls) +{ + struct BatchDepositContext *bdc = cls; + enum GNUNET_GenericReturnValue ret; + enum GNUNET_DB_QueryStatus qs; + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Signaling amount %s for KYC check during deposit\n", + TALER_amount2s (&bdc->accumulated_total_without_fee)); + ret = cb (cb_cls, + &bdc->accumulated_total_without_fee, + bdc->exchange_timestamp.abs_time); + GNUNET_break (GNUNET_SYSERR != ret); + if (GNUNET_OK != ret) + return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; + qs = TEH_plugin->select_deposit_amounts_for_kyc_check ( + TEH_plugin->cls, + &bdc->bd.wire_target_h_payto, + limit, + cb, + cb_cls); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Got %d additional transactions for this deposit and limit %llu\n", + qs, + (unsigned long long) limit.abs_value_us); + GNUNET_break (qs >= 0); + return qs; +} + + +/** + * Run KYC check. + * + * @param[in,out] bdc request context + */ +static void +bdc_phase_kyc (struct BatchDepositContext *bdc) +{ + if (GNUNET_YES != TEH_enable_kyc) + { + bdc->phase++; + return; + } + bdc->lch = TEH_legitimization_check2 ( + &bdc->rc->async_scope_id, + TALER_KYCLOGIC_KYC_TRIGGER_DEPOSIT, + bdc->bd.receiver_wire_account, + &bdc->bd.wire_target_h_payto, + &bdc->bd.merchant_pub, + &deposit_amount_cb, + bdc, + &deposit_legi_cb, + bdc); + GNUNET_assert (NULL != bdc->lch); + GNUNET_CONTAINER_DLL_insert (bdc_head, + bdc_tail, + bdc); + MHD_suspend_connection (bdc->rc->connection); + bdc->phase = BDC_PHASE_SUSPENDED; +} + + +/** + * Handle policy. + * + * @param[in,out] bdc request context + */ +static void +bdc_phase_policy (struct BatchDepositContext *bdc) +{ + const char *error_hint = NULL; + + if (bdc->has_no_policy) + { + bdc->phase++; + return; + } + if (GNUNET_OK != + TALER_extensions_create_policy_details ( + TEH_currency, + bdc->policy_json, + &bdc->policy_details, + &error_hint)) + { + GNUNET_break_op (0); + finish_loop (bdc, + TALER_MHD_reply_with_error ( + bdc->rc->connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_EXCHANGE_DEPOSITS_POLICY_NOT_ACCEPTED, + error_hint)); + return; + } + + TALER_deposit_policy_hash (bdc->policy_json, + &bdc->h_policy); + bdc->phase++; +} + + +/** * Parse per-coin deposit information from @a jcoin * into @a deposit. Fill in generic information from * @a ctx. * - * @param connection connection we are handling - * @param dc information about the overall batch + * @param bdc information about the overall batch * @param jcoin coin data to parse * @param[out] cdi where to store the result * @param[out] deposit_fee where to write the deposit fee @@ -308,13 +683,12 @@ batch_deposit_transaction (void *cls, * #GNUNET_SYSERR on failure and no error could be returned */ static enum GNUNET_GenericReturnValue -parse_coin (struct MHD_Connection *connection, - const struct BatchDepositContext *dc, +parse_coin (const struct BatchDepositContext *bdc, json_t *jcoin, struct TALER_EXCHANGEDB_CoinDepositInformation *cdi, struct TALER_Amount *deposit_fee) { - const struct TALER_EXCHANGEDB_BatchDeposit *bd = &dc->bd; + const struct TALER_EXCHANGEDB_BatchDeposit *bd = &bdc->bd; struct GNUNET_JSON_Specification spec[] = { TALER_JSON_spec_amount ("contribution", TEH_currency, @@ -336,7 +710,7 @@ parse_coin (struct MHD_Connection *connection, enum GNUNET_GenericReturnValue res; if (GNUNET_OK != - (res = TALER_MHD_parse_json_data (connection, + (res = TALER_MHD_parse_json_data (bdc->rc->connection, jcoin, spec))) return res; @@ -345,9 +719,10 @@ parse_coin (struct MHD_Connection *connection, struct TEH_DenominationKey *dk; MHD_RESULT mret; - dk = TEH_keys_denomination_by_hash (&cdi->coin.denom_pub_hash, - connection, - &mret); + dk = TEH_keys_denomination_by_hash ( + &cdi->coin.denom_pub_hash, + bdc->rc->connection, + &mret); if (NULL == dk) { GNUNET_JSON_parse_free (spec); @@ -361,10 +736,11 @@ parse_coin (struct MHD_Connection *connection, GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); return (MHD_YES == - TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_EXCHANGE_GENERIC_AMOUNT_EXCEEDS_DENOMINATION_VALUE, - NULL)) + TALER_MHD_reply_with_error ( + bdc->rc->connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_EXCHANGE_GENERIC_AMOUNT_EXCEEDS_DENOMINATION_VALUE, + NULL)) ? GNUNET_NO : GNUNET_SYSERR; } @@ -374,7 +750,7 @@ parse_coin (struct MHD_Connection *connection, GNUNET_JSON_parse_free (spec); return (MHD_YES == TEH_RESPONSE_reply_expired_denom_pub_hash ( - connection, + bdc->rc->connection, &cdi->coin.denom_pub_hash, TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED, "DEPOSIT")) @@ -387,7 +763,7 @@ parse_coin (struct MHD_Connection *connection, GNUNET_JSON_parse_free (spec); return (MHD_YES == TEH_RESPONSE_reply_expired_denom_pub_hash ( - connection, + bdc->rc->connection, &cdi->coin.denom_pub_hash, TALER_EC_EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE, "DEPOSIT")) @@ -400,7 +776,7 @@ parse_coin (struct MHD_Connection *connection, GNUNET_JSON_parse_free (spec); return (MHD_YES == TEH_RESPONSE_reply_expired_denom_pub_hash ( - connection, + bdc->rc->connection, &cdi->coin.denom_pub_hash, TALER_EC_EXCHANGE_GENERIC_DENOMINATION_REVOKED, "DEPOSIT")) @@ -413,10 +789,11 @@ parse_coin (struct MHD_Connection *connection, /* denomination cipher and denomination signature cipher not the same */ GNUNET_JSON_parse_free (spec); return (MHD_YES == - TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_EXCHANGE_GENERIC_CIPHER_MISMATCH, - NULL)) + TALER_MHD_reply_with_error ( + bdc->rc->connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_EXCHANGE_GENERIC_CIPHER_MISMATCH, + NULL)) ? GNUNET_NO : GNUNET_SYSERR; } @@ -441,10 +818,11 @@ parse_coin (struct MHD_Connection *connection, TALER_LOG_WARNING ("Invalid coin passed for /batch-deposit\n"); GNUNET_JSON_parse_free (spec); return (MHD_YES == - TALER_MHD_reply_with_error (connection, - MHD_HTTP_FORBIDDEN, - TALER_EC_EXCHANGE_DENOMINATION_SIGNATURE_INVALID, - NULL)) + TALER_MHD_reply_with_error ( + bdc->rc->connection, + MHD_HTTP_FORBIDDEN, + TALER_EC_EXCHANGE_DENOMINATION_SIGNATURE_INVALID, + NULL)) ? GNUNET_NO : GNUNET_SYSERR; } @@ -455,10 +833,11 @@ parse_coin (struct MHD_Connection *connection, GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); return (MHD_YES == - TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_EXCHANGE_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE, - NULL)) + TALER_MHD_reply_with_error ( + bdc->rc->connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_EXCHANGE_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE, + NULL)) ? GNUNET_NO : GNUNET_SYSERR; } @@ -468,13 +847,13 @@ parse_coin (struct MHD_Connection *connection, TALER_wallet_deposit_verify ( &cdi->amount_with_fee, deposit_fee, - &dc->h_wire, + &bdc->h_wire, &bd->h_contract_terms, &bd->wallet_data_hash, cdi->coin.no_age_commitment ? NULL : &cdi->coin.h_age_commitment, - NULL != dc->policy_json ? &dc->h_policy : NULL, + NULL != bdc->policy_json ? &bdc->h_policy : NULL, &cdi->coin.denom_pub_hash, bd->wallet_timestamp, &bd->merchant_pub, @@ -485,10 +864,11 @@ parse_coin (struct MHD_Connection *connection, TALER_LOG_WARNING ("Invalid signature on /batch-deposit request\n"); GNUNET_JSON_parse_free (spec); return (MHD_YES == - TALER_MHD_reply_with_error (connection, - MHD_HTTP_FORBIDDEN, - TALER_EC_EXCHANGE_DEPOSIT_COIN_SIGNATURE_INVALID, - TALER_B2S (&cdi->coin.coin_pub))) + TALER_MHD_reply_with_error ( + bdc->rc->connection, + MHD_HTTP_FORBIDDEN, + TALER_EC_EXCHANGE_DEPOSIT_COIN_SIGNATURE_INVALID, + TALER_B2S (&cdi->coin.coin_pub))) ? GNUNET_NO : GNUNET_SYSERR; } @@ -496,15 +876,19 @@ parse_coin (struct MHD_Connection *connection, } -MHD_RESULT -TEH_handler_batch_deposit (struct TEH_RequestContext *rc, - const json_t *root, - const char *const args[]) +/** + * Run processing phase that parses the request. + * + * @param[in,out] bdc request context + * @param root JSON object that was POSTed + */ +static void +bdc_phase_parse (struct BatchDepositContext *bdc, + const json_t *root) { - struct MHD_Connection *connection = rc->connection; - struct BatchDepositContext dc = { 0 }; - struct TALER_EXCHANGEDB_BatchDeposit *bd = &dc.bd; + struct TALER_EXCHANGEDB_BatchDeposit *bd = &bdc->bd; const json_t *coins; + const json_t *policy_json; bool no_refund_deadline = true; struct GNUNET_JSON_Specification spec[] = { TALER_JSON_spec_payto_uri ("merchant_payto_uri", @@ -522,9 +906,9 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc, GNUNET_JSON_spec_array_const ("coins", &coins), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_json ("policy", - &dc.policy_json), - &dc.has_no_policy), + GNUNET_JSON_spec_object_const ("policy", + &policy_json), + &bdc->has_no_policy), GNUNET_JSON_spec_timestamp ("timestamp", &bd->wallet_timestamp), GNUNET_JSON_spec_mark_optional ( @@ -536,24 +920,34 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc, GNUNET_JSON_spec_end () }; - (void) args; { enum GNUNET_GenericReturnValue res; - res = TALER_MHD_parse_json_data (connection, + res = TALER_MHD_parse_json_data (bdc->rc->connection, root, spec); if (GNUNET_SYSERR == res) { + /* hard failure */ GNUNET_break (0); - return MHD_NO; /* hard failure */ + finish_loop (bdc, + MHD_NO); + return; } if (GNUNET_NO == res) { + /* failure */ GNUNET_break_op (0); - return MHD_YES; /* failure */ + finish_loop (bdc, + MHD_YES); + return; } } + bdc->policy_json + = json_incref ((json_t *) policy_json); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Batch deposit into contract %s\n", + GNUNET_h2s (&bd->h_contract_terms.hash)); /* validate merchant's wire details (as far as we can) */ { @@ -566,12 +960,14 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc, GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); - ret = TALER_MHD_reply_with_error (connection, + ret = TALER_MHD_reply_with_error (bdc->rc->connection, MHD_HTTP_BAD_REQUEST, TALER_EC_GENERIC_PARAMETER_MALFORMED, emsg); GNUNET_free (emsg); - return ret; + finish_loop (bdc, + ret); + return; } } if (GNUNET_TIME_timestamp_cmp (bd->refund_deadline, @@ -580,156 +976,181 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc, { GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_EXCHANGE_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE, - NULL); + finish_loop (bdc, + TALER_MHD_reply_with_error ( + bdc->rc->connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_EXCHANGE_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE, + NULL)); + return; } if (GNUNET_TIME_absolute_is_never (bd->wire_deadline.abs_time)) { GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_EXCHANGE_DEPOSIT_WIRE_DEADLINE_IS_NEVER, - NULL); + finish_loop (bdc, + TALER_MHD_reply_with_error ( + bdc->rc->connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_EXCHANGE_DEPOSIT_WIRE_DEADLINE_IS_NEVER, + NULL)); + return; } TALER_payto_hash (bd->receiver_wire_account, &bd->wire_target_h_payto); TALER_merchant_wire_signature_hash (bd->receiver_wire_account, &bd->wire_salt, - &dc.h_wire); - - GNUNET_assert (GNUNET_OK == - TALER_amount_set_zero (TEH_currency, - &dc.accumulated_total_without_fee)); - - /* handle policy, if present */ - if (! dc.has_no_policy) - { - const char *error_hint = NULL; - - if (GNUNET_OK != - TALER_extensions_create_policy_details ( - TEH_currency, - dc.policy_json, - &dc.policy_details, - &error_hint)) - { - GNUNET_break_op (0); - GNUNET_JSON_parse_free (spec); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_EXCHANGE_DEPOSITS_POLICY_NOT_ACCEPTED, - error_hint); - } - - TALER_deposit_policy_hash (dc.policy_json, - &dc.h_policy); - } - + &bdc->h_wire); bd->num_cdis = json_array_size (coins); if (0 == bd->num_cdis) { GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "coins"); + finish_loop (bdc, + TALER_MHD_reply_with_error ( + bdc->rc->connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + "coins")); + return; } if (TALER_MAX_FRESH_COINS < bd->num_cdis) { GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "coins"); + finish_loop (bdc, + TALER_MHD_reply_with_error ( + bdc->rc->connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + "coins")); + return; } + bdc->cdis + = GNUNET_new_array (bd->num_cdis, + struct TALER_EXCHANGEDB_CoinDepositInformation); + bdc->deposit_fees + = GNUNET_new_array (bd->num_cdis, + struct TALER_Amount); + bd->cdis = bdc->cdis; + for (unsigned i = 0; i<bd->num_cdis; i++) { - struct TALER_EXCHANGEDB_CoinDepositInformation cdis[ - GNUNET_NZL (bd->num_cdis)]; - struct TALER_Amount deposit_fees[GNUNET_NZL (bd->num_cdis)]; + struct TALER_Amount amount_without_fee; enum GNUNET_GenericReturnValue res; - unsigned int i; - bd->cdis = cdis; - dc.deposit_fees = deposit_fees; - for (i = 0; i<bd->num_cdis; i++) - { - struct TALER_Amount amount_without_fee; - - res = parse_coin (connection, - &dc, - json_array_get (coins, - i), - &cdis[i], - &deposit_fees[i]); - if (GNUNET_OK != res) - break; - GNUNET_assert (0 <= - TALER_amount_subtract ( - &amount_without_fee, - &cdis[i].amount_with_fee, - &deposit_fees[i])); - - GNUNET_assert (0 <= - TALER_amount_add ( - &dc.accumulated_total_without_fee, - &dc.accumulated_total_without_fee, - &amount_without_fee)); - } + res = parse_coin (bdc, + json_array_get (coins, + i), + &bdc->cdis[i], + &bdc->deposit_fees[i]); if (GNUNET_OK != res) { - for (unsigned int j = 0; j<i; j++) - TALER_denom_sig_free (&cdis[j].coin.denom_sig); - GNUNET_JSON_parse_free (spec); - return (GNUNET_NO == res) ? MHD_YES : MHD_NO; + finish_loop (bdc, + (GNUNET_NO == res) + ? MHD_YES + : MHD_NO); + return; } + GNUNET_assert (0 <= + TALER_amount_subtract ( + &amount_without_fee, + &bdc->cdis[i].amount_with_fee, + &bdc->deposit_fees[i])); - dc.exchange_timestamp = GNUNET_TIME_timestamp_get (); - if (GNUNET_SYSERR == - TEH_plugin->preflight (TEH_plugin->cls)) - { - GNUNET_break (0); - GNUNET_JSON_parse_free (spec); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_START_FAILED, - "preflight failure"); - } + GNUNET_assert (0 <= + TALER_amount_add ( + &bdc->accumulated_total_without_fee, + &bdc->accumulated_total_without_fee, + &amount_without_fee)); + } - /* execute transaction */ - { - MHD_RESULT mhd_ret; - - if (GNUNET_OK != - TEH_DB_run_transaction (connection, - "execute batch deposit", - TEH_MT_REQUEST_BATCH_DEPOSIT, - &mhd_ret, - &batch_deposit_transaction, - &dc)) - { - for (unsigned int j = 0; j<bd->num_cdis; j++) - TALER_denom_sig_free (&cdis[j].coin.denom_sig); - GNUNET_JSON_parse_free (spec); - return mhd_ret; - } - } + GNUNET_JSON_parse_free (spec); + bdc->phase++; +} - /* generate regular response */ - { - MHD_RESULT mhd_ret; - mhd_ret = reply_batch_deposit_success (connection, - &dc); - for (unsigned int j = 0; j<bd->num_cdis; j++) - TALER_denom_sig_free (&cdis[j].coin.denom_sig); - GNUNET_JSON_parse_free (spec); - return mhd_ret; +/** + * Function called to clean up a context. + * + * @param rc request context with data to clean up + */ +static void +bdc_cleaner (struct TEH_RequestContext *rc) +{ + struct BatchDepositContext *bdc = rc->rh_ctx; + + if (NULL != bdc->lch) + { + TEH_legitimization_check_cancel (bdc->lch); + bdc->lch = NULL; + } + for (unsigned int i = 0; i<bdc->bd.num_cdis; i++) + TALER_denom_sig_free (&bdc->cdis[i].coin.denom_sig); + GNUNET_free (bdc->cdis); + GNUNET_free (bdc->deposit_fees); + json_decref (bdc->policy_json); + GNUNET_free (bdc); +} + + +MHD_RESULT +TEH_handler_batch_deposit (struct TEH_RequestContext *rc, + const json_t *root, + const char *const args[]) +{ + struct BatchDepositContext *bdc = rc->rh_ctx; + + (void) args; + if (NULL == bdc) + { + bdc = GNUNET_new (struct BatchDepositContext); + bdc->rc = rc; + rc->rh_ctx = bdc; + rc->rh_cleaner = &bdc_cleaner; + bdc->phase = BDC_PHASE_PARSE; + bdc->exchange_timestamp = GNUNET_TIME_timestamp_get (); + GNUNET_assert (GNUNET_OK == + TALER_amount_set_zero (TEH_currency, + &bdc->accumulated_total_without_fee)); + } + while (1) + { + switch (bdc->phase) + { + case BDC_PHASE_INIT: + GNUNET_break (0); + bdc->phase = BDC_PHASE_RETURN_NO; + break; + case BDC_PHASE_PARSE: + bdc_phase_parse (bdc, + root); + break; + case BDC_PHASE_POLICY: + bdc_phase_policy (bdc); + break; + case BDC_PHASE_KYC: + bdc_phase_kyc (bdc); + break; + case BDC_PHASE_TRANSACT: + bdc_phase_transact (bdc); + break; + case BDC_PHASE_REPLY_SUCCESS: + bdc_phase_reply_success (bdc); + break; + case BDC_PHASE_SUSPENDED: + return MHD_YES; + case BDC_PHASE_CHECK_KYC_RESULT: + bdc_phase_check_kyc_result (bdc); + break; + case BDC_PHASE_GENERATE_REPLY_FAILURE: + return MHD_queue_response (bdc->rc->connection, + bdc->http_status, + bdc->response); + case BDC_PHASE_RETURN_YES: + return MHD_YES; + case BDC_PHASE_RETURN_NO: + return MHD_NO; } } } diff --git a/src/exchange/taler-exchange-httpd_batch-deposit.h b/src/exchange/taler-exchange-httpd_batch-deposit.h index 187fb9f20..b5b7b0a32 100644 --- a/src/exchange/taler-exchange-httpd_batch-deposit.h +++ b/src/exchange/taler-exchange-httpd_batch-deposit.h @@ -29,6 +29,14 @@ /** + * Resumes all suspended batch deposit requests + * during cleanup. + */ +void +TEH_batch_deposit_cleanup (void); + + +/** * Handle a "/batch-deposit" request. Parses the JSON, and, if * successful, passes the JSON data to #deposit_transaction() to * further check the details of the operation specified. If everything checks diff --git a/src/exchange/taler-exchange-httpd_batch-withdraw.c b/src/exchange/taler-exchange-httpd_batch-withdraw.c index 6fb3c5447..cc61b98e7 100644 --- a/src/exchange/taler-exchange-httpd_batch-withdraw.c +++ b/src/exchange/taler-exchange-httpd_batch-withdraw.c @@ -571,7 +571,8 @@ check_kyc_result (struct BatchWithdrawContext *bwc) TEH_RESPONSE_reply_kyc_required ( bwc->rc->connection, &bwc->h_payto, - &bwc->kyc)); + &bwc->kyc, + false)); return; } bwc->phase++; @@ -672,6 +673,11 @@ run_legi_check (struct BatchWithdrawContext *bwc) enum GNUNET_DB_QueryStatus qs; char *payto_uri; + if (GNUNET_YES != TEH_enable_kyc) + { + bwc->phase = BWC_PHASE_PREPARE_TRANSACTION; + return; + } /* Check if the money came from a wire transfer */ qs = TEH_plugin->reserves_get_origin ( TEH_plugin->cls, @@ -702,7 +708,7 @@ run_legi_check (struct BatchWithdrawContext *bwc) TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW, payto_uri, &bwc->h_payto, - NULL, + NULL, /* no account pub: this is about the origin account */ &withdraw_amount_cb, bwc, &withdraw_legi_cb, diff --git a/src/exchange/taler-exchange-httpd_coins_get.c b/src/exchange/taler-exchange-httpd_coins_get.c index 8644395e5..7c192b26a 100644 --- a/src/exchange/taler-exchange-httpd_coins_get.c +++ b/src/exchange/taler-exchange-httpd_coins_get.c @@ -609,6 +609,7 @@ TEH_handler_coins_get (struct TEH_RequestContext *rc, enum GNUNET_DB_QueryStatus qs; qs = TEH_plugin->get_coin_transactions (TEH_plugin->cls, + true, coin_pub, start_off, etag_in, @@ -654,9 +655,8 @@ TEH_handler_coins_get (struct TEH_RequestContext *rc, if (NULL == tl) { /* 204: empty history */ - resp = MHD_create_response_from_buffer (0, - "", - MHD_RESPMEM_PERSISTENT); + resp = MHD_create_response_from_buffer_static (0, + ""); http_status = MHD_HTTP_NO_CONTENT; } else diff --git a/src/exchange/taler-exchange-httpd_common_kyc.c b/src/exchange/taler-exchange-httpd_common_kyc.c index 0ac1fbc25..05d1ffc8c 100644 --- a/src/exchange/taler-exchange-httpd_common_kyc.c +++ b/src/exchange/taler-exchange-httpd_common_kyc.c @@ -157,7 +157,6 @@ fallback_result_cb (void *cls, kat->fb = NULL; (void) requirement_row; - // FIXME: return new requirement_row!? GNUNET_async_scope_enter (&kat->scope, &old_scope); if (result) @@ -478,32 +477,6 @@ add_kyc_history_entry ( } -/** - * We have finished a KYC process and obtained new - * @a attributes for a given @a account_id. - * Check with the KYC-AML trigger to see if we need - * to initiate an AML process, and store the attributes - * in the database. Then call @a cb. - * - * @param scope the HTTP request logging scope - * @param process_row legitimization process the data provided is about, - * or must be 0 if instant_ms is given - * @param instant_ms instant measure to run, used if @a process_row is 0, - * otherwise must be NULL - * @param account_id account the webhook was about - * @param provider_name name of the provider with the logic that was run - * @param provider_user_id set to user ID at the provider, or - * NULL if not supported or unknown - * @param provider_legitimization_id set to legitimization process ID at the provider, - * or NULL if not supported or unknown - * @param expiration until when is the KYC check valid - * @param attributes user attributes returned by the provider - * @param http_status HTTP status code of @a response - * @param[in] response to return to the HTTP client, can be NULL - * @param cb function to call with the result - * @param cb_cls closure for @a cb - * @return handle to cancel the operation - */ struct TEH_KycAmlTrigger * TEH_kyc_finished2 ( const struct GNUNET_AsyncScopeId *scope, @@ -771,7 +744,7 @@ handle_aml_fallback_result ( if (! TEH_kyc_failed ( fb->orig_requirement_row, &fb->account_id, - NULL, + "FALLBACK", NULL, NULL, apr->details.failure.error_message, @@ -923,16 +896,19 @@ TEH_kyc_fallback ( { json_t *jmeasures; enum GNUNET_DB_QueryStatus qs; + bool bad_kyc_auth; jmeasures = TALER_KYCLOGIC_check_to_measures (&kcc); qs = TEH_plugin->trigger_kyc_rule_for_account ( TEH_plugin->cls, NULL, /* account_id is already in wire targets */ account_id, - NULL, + NULL, /* account_pub */ + NULL, /* merchant_pub */ jmeasures, 65536, /* high priority (does it matter?) */ - &fb->requirement_row); + &fb->requirement_row, + &bad_kyc_auth); json_decref (jmeasures); fb->failure = (qs <= 0); fb->task = GNUNET_SCHEDULER_add_now (&return_fallback_result, @@ -1044,11 +1020,23 @@ struct TEH_LegitimizationCheckHandle struct TALER_PaytoHashP h_payto; /** - * Public key of the account. + * Public key of the account. We should associate this public + * key with the account if @e have_account_pub is true. Do not + * confuse with @e lcr.kyc.have_account_pub which refers to us + * already having an @e lcr.kyc.account_pub in the database for + * the given @e h_payto. */ union TALER_AccountPublicKeyP account_pub; /** + * Public key of the merchant. Checks that the KYC + * data was actually provided for this merchant if + * @e have_merchant_pub is true, and if not rejects + * the operation. + */ + struct TALER_MerchantPublicKeyP merchant_pub; + + /** * Our request scope for logging. */ struct GNUNET_AsyncScopeId scope; @@ -1074,6 +1062,12 @@ struct TEH_LegitimizationCheckHandle * Do we have @e account_pub? */ bool have_account_pub; + + /** + * Do we have @e merchant_pub? + */ + bool have_merchant_pub; + }; @@ -1087,13 +1081,16 @@ static void async_return_legi_result (void *cls) { struct TEH_LegitimizationCheckHandle *lch = cls; + struct GNUNET_AsyncScopeSave old_scope; lch->async_task = NULL; - // FIXME: enter (+exit) lch->scope... + GNUNET_async_scope_enter (&lch->scope, + &old_scope); lch->result_cb (lch->result_cb_cls, &lch->lcr); lch->lcr.response = NULL; TEH_legitimization_check_cancel (lch); + GNUNET_async_scope_restore (&old_scope); } @@ -1174,8 +1171,23 @@ legi_check_aml_trigger_cb ( } -struct TEH_LegitimizationCheckHandle * -TEH_legitimization_check ( +/** + * Setup legitimization check. + * + * @param scope scope for logging + * @param et type of event we are checking + * @param payto_uri account we are checking for + * @param h_payto hash of @a payto_uri + * @param account_pub public key to enable for the + * KYC authorization, NULL if not known + * @param ai callback to get amounts involved historically + * @param ai_cls closure for @a ai + * @param result_cb function to call with the result + * @param result_cb_cls closure for @a result_cb + * @return handle for the operation + */ +static struct TEH_LegitimizationCheckHandle * +setup_legitimization_check ( const struct GNUNET_AsyncScopeId *scope, enum TALER_KYCLOGIC_KycTriggerEvent et, const char *payto_uri, @@ -1202,6 +1214,63 @@ TEH_legitimization_check ( lch->ai_cls = ai_cls; lch->result_cb = result_cb; lch->result_cb_cls = result_cb_cls; + return lch; +} + + +struct TEH_LegitimizationCheckHandle * +TEH_legitimization_check ( + const struct GNUNET_AsyncScopeId *scope, + enum TALER_KYCLOGIC_KycTriggerEvent et, + const char *payto_uri, + const struct TALER_PaytoHashP *h_payto, + const union TALER_AccountPublicKeyP *account_pub, + TALER_KYCLOGIC_KycAmountIterator ai, + void *ai_cls, + TEH_LegitimizationCheckCallback result_cb, + void *result_cb_cls) +{ + struct TEH_LegitimizationCheckHandle *lch; + + lch = setup_legitimization_check (scope, + et, + payto_uri, + h_payto, + account_pub, + ai, + ai_cls, + result_cb, + result_cb_cls); + legitimization_check_run (lch); + return lch; +} + + +struct TEH_LegitimizationCheckHandle * +TEH_legitimization_check2 ( + const struct GNUNET_AsyncScopeId *scope, + enum TALER_KYCLOGIC_KycTriggerEvent et, + const char *payto_uri, + const struct TALER_PaytoHashP *h_payto, + const struct TALER_MerchantPublicKeyP *merchant_pub, + TALER_KYCLOGIC_KycAmountIterator ai, + void *ai_cls, + TEH_LegitimizationCheckCallback result_cb, + void *result_cb_cls) +{ + struct TEH_LegitimizationCheckHandle *lch; + + lch = setup_legitimization_check (scope, + et, + payto_uri, + h_payto, + NULL, + ai, + ai_cls, + result_cb, + result_cb_cls); + lch->merchant_pub = *merchant_pub; + lch->have_merchant_pub = true; legitimization_check_run (lch); return lch; } @@ -1394,9 +1463,11 @@ run_check ( lch->payto_uri, &lch->h_payto, lch->have_account_pub ? &lch->account_pub : NULL, + lch->have_merchant_pub ? &lch->merchant_pub : NULL, jmeasures, 0, /* no particular priority */ - &lch->lcr.kyc.requirement_row); + &lch->lcr.kyc.requirement_row, + &lch->lcr.bad_kyc_auth); switch (qs) { case GNUNET_DB_STATUS_HARD_ERROR: @@ -1415,6 +1486,13 @@ run_check ( case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: break; } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "trigger_kyc_rule_for_account-2 on %d/%d returned %d/%llu/%d\n", + lch->have_account_pub, + lch->have_merchant_pub, + (int) qs, + (unsigned long long) lch->lcr.kyc.requirement_row, + lch->lcr.bad_kyc_auth); /* return success! */ lch->async_task = GNUNET_SCHEDULER_add_now ( @@ -1426,6 +1504,78 @@ cleanup: } +/** + * The KYC check failed because KYC auth is required + * to match and it does not. + * + * @param[in,out] lch legitimization check to fail + */ +static void +fail_kyc_auth (struct TEH_LegitimizationCheckHandle *lch) +{ + lch->lcr.kyc.requirement_row = 0; + lch->lcr.kyc.ok = false; + lch->lcr.bad_kyc_auth = true; + lch->lcr.expiration_date + = GNUNET_TIME_UNIT_FOREVER_TS; + memset (&lch->lcr.next_threshold, + 0, + sizeof (struct TALER_Amount)); + lch->lcr.http_status = 0; + lch->lcr.response = NULL; + lch->async_task + = GNUNET_SCHEDULER_add_now ( + &async_return_legi_result, + lch); +} + + +/** + * Function called to iterate over KYC-relevant + * transaction amounts for a particular time range. + * Called within a database transaction, so must + * not start a new one. + * + * Given that there *is* a KYC requirement, we also + * check if the kyc_auth_bad is set and react + * accordingly. + * + * @param cls closure, a `struct TEH_LegitimizationCheckHandle *` + * @param limit maximum time-range for which events + * should be fetched (timestamp in the past) + * @param cb function to call on each event found, + * events must be returned in reverse chronological + * order + * @param cb_cls closure for @a cb + * @return transaction status + */ +static enum GNUNET_DB_QueryStatus +amount_iterator_wrapper_cb ( + void *cls, + struct GNUNET_TIME_Absolute limit, + TALER_EXCHANGEDB_KycAmountCallback cb, + void *cb_cls) +{ + struct TEH_LegitimizationCheckHandle *lch = cls; + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "KYC: Checking amounts until %s\n", + GNUNET_TIME_absolute2s (limit)); + if (lch->lcr.bad_kyc_auth) + { + /* We *do* have applicable KYC rules *and* the + target_pub does not match the merchant_pub, + so we indeed have a problem! */ + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "KYC: Mismatch between merchant_pub and target_pub is relevant!\n"); + } + return lch->ai (lch->ai_cls, + limit, + cb, + cb_cls); +} + + static void legitimization_check_run ( struct TEH_LegitimizationCheckHandle *lch) @@ -1434,12 +1584,14 @@ legitimization_check_run ( const struct TALER_KYCLOGIC_KycRule *requirement; enum GNUNET_DB_QueryStatus qs; const struct TALER_KYCLOGIC_Measure *instant_ms; + struct GNUNET_AsyncScopeSave old_scope; if (! TEH_enable_kyc) { /* AML/KYC disabled, just immediately return success! */ lch->lcr.kyc.requirement_row = 0; lch->lcr.kyc.ok = true; + lch->lcr.bad_kyc_auth = false; lch->lcr.expiration_date = GNUNET_TIME_UNIT_FOREVER_TS; memset (&lch->lcr.next_threshold, @@ -1453,28 +1605,94 @@ legitimization_check_run ( lch); return; } - // FIXME: enter (+exit) lch->scope! + GNUNET_async_scope_enter (&lch->scope, + &old_scope); { json_t *jrules; + bool no_account_pub; + bool no_reserve_pub; - qs = TEH_plugin->get_kyc_rules (TEH_plugin->cls, - &lch->h_payto, - &jrules); - if (qs < 0) + qs = TEH_plugin->get_kyc_rules ( + TEH_plugin->cls, + &lch->h_payto, + &no_account_pub, + &lch->lcr.kyc.account_pub, + &no_reserve_pub, + &lch->lcr.reserve_pub.reserve_pub, + &jrules); + switch (qs) { + case GNUNET_DB_STATUS_HARD_ERROR: + case GNUNET_DB_STATUS_SOFT_ERROR: GNUNET_break (0); legi_fail (lch, TALER_EC_GENERIC_DB_FETCH_FAILED, "get_kyc_rules"); + GNUNET_async_scope_restore (&old_scope); return; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + break; } - if (qs > 0) + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "get_kyc_rules returned %d/%d/%d\n", + (int) qs, + ! no_account_pub, + ! no_reserve_pub); + + lch->lcr.kyc.have_account_pub + = ! no_account_pub; + lch->lcr.have_reserve_pub + = ! no_reserve_pub; + if ( (lch->have_merchant_pub) && + ( (! lch->lcr.kyc.have_account_pub) || + (0 != + GNUNET_memcmp (&lch->merchant_pub, + &lch->lcr.kyc.account_pub.merchant_pub)) ) && + ( (! lch->lcr.have_reserve_pub) || + (0 != + GNUNET_memcmp (&lch->merchant_pub, + &lch->lcr.reserve_pub.merchant_pub)) ) ) { + if (NULL == jrules) + { + /* We do not have custom rules, defer enforcing merchant_pub + match until we actually have deposit constraints */ + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "KYC: merchant_pub given but no known target_pub(%d)/reserve_pub(%d) match (%d)!\n", + lch->lcr.kyc.have_account_pub, + lch->lcr.have_reserve_pub, + (int) qs); + lch->lcr.bad_kyc_auth = true; + } + else + { + /* We have custom rules, but the target_pub for + those custom rules does not match the + merchant_pub. Fail the KYC process! */ + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "KYC: merchant_pub does not match target_pub of custom rules!\n"); + json_decref (jrules); + fail_kyc_auth (lch); + return; + } + } + + /* parse and free jrules (if we had any) */ + if (NULL != jrules) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "KYC: have custom KYC rules for this account!\n"); lrs = TALER_KYCLOGIC_rules_parse (jrules); GNUNET_break (NULL != lrs); /* Fall back to default rules on parse error! */ json_decref (jrules); } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "KYC: default KYC rules apply to this account!\n"); + } } if (NULL != lrs) @@ -1512,21 +1730,32 @@ legitimization_check_run ( qs = TALER_KYCLOGIC_kyc_test_required ( lch->et, lrs, - lch->ai, - lch->ai_cls, + &amount_iterator_wrapper_cb, + lch, &requirement, &lch->lcr.next_threshold); if (qs < 0) { + GNUNET_break (0); TALER_KYCLOGIC_rules_free (lrs); legi_fail (lch, TALER_EC_GENERIC_DB_FETCH_FAILED, "kyc_test_required"); + GNUNET_async_scope_restore (&old_scope); + return; + } + if (lch->lcr.bad_kyc_auth) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "KYC auth required\n"); + fail_kyc_auth (lch); return; } if (NULL == requirement) { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "KYC check passed\n"); lch->lcr.kyc.ok = true; lch->lcr.expiration_date = TALER_KYCLOGIC_rules_get_expiration (lrs); @@ -1539,6 +1768,7 @@ legitimization_check_run ( = GNUNET_SCHEDULER_add_now ( &async_return_legi_result, lch); + GNUNET_async_scope_restore (&old_scope); return; } @@ -1579,8 +1809,10 @@ legitimization_check_run ( legi_fail (lch, TALER_EC_EXCHANGE_KYC_AML_PROGRAM_FAILURE, NULL); + GNUNET_async_scope_restore (&old_scope); return; } + GNUNET_async_scope_restore (&old_scope); return; } @@ -1597,9 +1829,18 @@ legitimization_check_run ( lch->payto_uri, &lch->h_payto, lch->have_account_pub ? &lch->account_pub : NULL, + lch->have_merchant_pub ? &lch->merchant_pub : NULL, jmeasures, TALER_KYCLOGIC_rule2priority (requirement), - &lch->lcr.kyc.requirement_row); + &lch->lcr.kyc.requirement_row, + &lch->lcr.bad_kyc_auth); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "trigger_kyc_rule_for_account-1 on %d/%d returned %d/%llu/%d\n", + lch->have_account_pub, + lch->have_merchant_pub, + (int) qs, + (unsigned long long) lch->lcr.kyc.requirement_row, + lch->lcr.bad_kyc_auth); json_decref (jmeasures); } if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) @@ -1608,6 +1849,7 @@ legitimization_check_run ( legi_fail (lch, TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, "trigger_kyc_rule_for_account"); + GNUNET_async_scope_restore (&old_scope); return; } TALER_KYCLOGIC_rules_free (lrs); @@ -1617,6 +1859,7 @@ legitimization_check_run ( legi_fail (lch, TALER_EC_GENERIC_DB_STORE_FAILED, "trigger_kyc_rule_for_account"); + GNUNET_async_scope_restore (&old_scope); return; } /* return success! */ @@ -1624,6 +1867,7 @@ legitimization_check_run ( = GNUNET_SCHEDULER_add_now ( &async_return_legi_result, lch); + GNUNET_async_scope_restore (&old_scope); } diff --git a/src/exchange/taler-exchange-httpd_common_kyc.h b/src/exchange/taler-exchange-httpd_common_kyc.h index cd753746b..af9e22bca 100644 --- a/src/exchange/taler-exchange-httpd_common_kyc.h +++ b/src/exchange/taler-exchange-httpd_common_kyc.h @@ -87,6 +87,48 @@ TEH_kyc_finished ( TEH_KycAmlTriggerCallback cb, void *cb_cls); +/** + * We have finished a KYC process and obtained new + * @a attributes for a given @a account_id. + * Check with the KYC-AML trigger to see if we need + * to initiate an AML process, and store the attributes + * in the database. Then call @a cb. + * + * @param scope the HTTP request logging scope + * @param process_row legitimization process the data provided is about, + * or must be 0 if instant_ms is given + * @param instant_ms instant measure to run, used if @a process_row is 0, + * otherwise must be NULL + * @param account_id account the webhook was about + * @param provider_name name of the provider with the logic that was run + * @param provider_user_id set to user ID at the provider, or + * NULL if not supported or unknown + * @param provider_legitimization_id set to legitimization process ID at the provider, + * or NULL if not supported or unknown + * @param expiration until when is the KYC check valid + * @param attributes user attributes returned by the provider + * @param http_status HTTP status code of @a response + * @param[in] response to return to the HTTP client, can be NULL + * @param cb function to call with the result + * @param cb_cls closure for @a cb + * @return handle to cancel the operation + */ +struct TEH_KycAmlTrigger * +TEH_kyc_finished2 ( + const struct GNUNET_AsyncScopeId *scope, + uint64_t process_row, + const struct TALER_KYCLOGIC_Measure *instant_ms, + const struct TALER_PaytoHashP *account_id, + const char *provider_name, + const char *provider_user_id, + const char *provider_legitimization_id, + struct GNUNET_TIME_Absolute expiration, + const json_t *attributes, + unsigned int http_status, + struct MHD_Response *response, + TEH_KycAmlTriggerCallback cb, + void *cb_cls); + /** * Cancel KYC finish operation. @@ -195,6 +237,12 @@ struct TEH_LegitimizationCheckResult struct TALER_EXCHANGEDB_KycStatus kyc; /** + * Last reserve public key of a wire transfer from + * the account to the exchange. + */ + union TALER_AccountPublicKeyP reserve_pub; + + /** * Smallest amount (over any timeframe) that may * require additional KYC checks (if @a kyc.ok). */ @@ -207,17 +255,30 @@ struct TEH_LegitimizationCheckResult struct GNUNET_TIME_Timestamp expiration_date; /** - * HTTP status code for @a response, or 0 - */ - unsigned int http_status; - - /** * Response to return. Note that the response must * be queued or destroyed by the callee. NULL * if the legitimization check was successful and the handler should return * a handler-specific result. */ struct MHD_Response *response; + + /** + * HTTP status code for @a response, or 0 + */ + unsigned int http_status; + + /** + * True if @e reserve_pub is set. + */ + bool have_reserve_pub; + + /** + * Set to true if the merchant public key does not + * match the public key we have on file for this + * target account (and thus a new KYC AUTH is + * required). + */ + bool bad_kyc_auth; }; @@ -268,6 +329,36 @@ TEH_legitimization_check ( /** + * Do legitimization check and enforce that the current + * public key associated with the account is the given + * merchant public key. + * + * @param scope scope for logging + * @param et type of event we are checking + * @param payto_uri account we are checking for + * @param h_payto hash of @a payto_uri + * @param merchant_pub public key that must match the + * KYC authorization + * @param ai callback to get amounts involved historically + * @param ai_cls closure for @a ai + * @param result_cb function to call with the result + * @param result_cb_cls closure for @a result_cb + * @return handle for the operation + */ +struct TEH_LegitimizationCheckHandle * +TEH_legitimization_check2 ( + const struct GNUNET_AsyncScopeId *scope, + enum TALER_KYCLOGIC_KycTriggerEvent et, + const char *payto_uri, + const struct TALER_PaytoHashP *h_payto, + const struct TALER_MerchantPublicKeyP *merchant_pub, + TALER_KYCLOGIC_KycAmountIterator ai, + void *ai_cls, + TEH_LegitimizationCheckCallback result_cb, + void *result_cb_cls); + + +/** * Cancel legitimization check. * * @param[in] lch handle of the check to cancel diff --git a/src/exchange/taler-exchange-httpd_config.c b/src/exchange/taler-exchange-httpd_config.c index 35d0705e9..48a7deec0 100644 --- a/src/exchange/taler-exchange-httpd_config.c +++ b/src/exchange/taler-exchange-httpd_config.c @@ -63,6 +63,9 @@ TEH_handler_config (struct TEH_RequestContext *rc, GNUNET_JSON_pack_array_steal ( "wallet_balance_limit_without_kyc", TALER_KYCLOGIC_get_wallet_thresholds ())), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("shopping_url", + TEH_shopping_url)), /* Deprecate? */ GNUNET_JSON_pack_array_steal ( "supported_kyc_requirements", diff --git a/src/exchange/taler-exchange-httpd_config.h b/src/exchange/taler-exchange-httpd_config.h index 036409778..486a8b83b 100644 --- a/src/exchange/taler-exchange-httpd_config.h +++ b/src/exchange/taler-exchange-httpd_config.h @@ -41,7 +41,7 @@ * * Returned via both /config and /keys endpoints. */ -#define EXCHANGE_PROTOCOL_VERSION "20:0:3" +#define EXCHANGE_PROTOCOL_VERSION "21:0:4" /** diff --git a/src/exchange/taler-exchange-httpd_deposits_get.c b/src/exchange/taler-exchange-httpd_deposits_get.c index 4787c74db..4cdacd7ef 100644 --- a/src/exchange/taler-exchange-httpd_deposits_get.c +++ b/src/exchange/taler-exchange-httpd_deposits_get.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2023 Taler Systems SA + Copyright (C) 2014-2024 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -25,6 +25,7 @@ #include <pthread.h> #include "taler_dbevents.h" #include "taler_json_lib.h" +#include "taler_util.h" #include "taler_mhd_lib.h" #include "taler_signatures.h" #include "taler-exchange-httpd_keys.h" @@ -75,6 +76,15 @@ struct DepositWtidContext struct TALER_MerchantPublicKeyP merchant; /** + * Public key for KYC operations on the target bank + * account for the wire transfer. All zero if no + * public key is accepted yet. In that case, the + * client should use the @e merchant public key for + * the KYC auth wire transfer. + */ + union TALER_AccountPublicKeyP account_pub; + + /** * The coin's public key. This is the value that must have been * signed (blindly) by the Exchange. */ @@ -122,17 +132,16 @@ struct DepositWtidContext struct TALER_EXCHANGEDB_KycStatus kyc; /** - * Set to #GNUNET_YES by #handle_wtid if the wire transfer is still pending - * (and the above were not set). - * Set to #GNUNET_SYSERR if there was a serious error. - */ - enum GNUNET_GenericReturnValue pending; - - /** * #GNUNET_YES if we were suspended, #GNUNET_SYSERR * if we were woken up due to shutdown. */ enum GNUNET_GenericReturnValue suspended; + + /** + * What do we long-poll for? Defaults to + * #TALER_DGLPT_OK if not given. + */ + enum TALER_DepositGetLongPollTarget lpt; }; @@ -171,15 +180,14 @@ TEH_deposits_get_cleanup () * A merchant asked for details about a deposit. Provide * them. Generates the 200 reply. * - * @param connection connection to the client * @param ctx details to respond with * @return MHD result code */ static MHD_RESULT reply_deposit_details ( - struct MHD_Connection *connection, const struct DepositWtidContext *ctx) { + struct MHD_Connection *connection = ctx->rc->connection; struct TALER_ExchangePublicKeyP pub; struct TALER_ExchangeSignatureP sig; enum TALER_ErrorCode ec; @@ -218,81 +226,6 @@ reply_deposit_details ( /** - * Execute a "deposits" GET. Returns the transfer information - * associated with the given deposit. - * - * If it returns a non-error code, the transaction logic MUST - * NOT queue a MHD response. IF it returns an hard error, the - * transaction logic MUST queue a MHD response and set @a mhd_ret. IF - * it returns the soft error code, the function MAY be called again to - * retry and MUST NOT queue a MHD response. - * - * @param cls closure of type `struct DepositWtidContext *` - * @param connection MHD request which triggered the transaction - * @param[out] mhd_ret set to MHD response status for @a connection, - * if transaction failed (!) - * @return transaction status - */ -static enum GNUNET_DB_QueryStatus -deposits_get_transaction (void *cls, - struct MHD_Connection *connection, - MHD_RESULT *mhd_ret) -{ - struct DepositWtidContext *ctx = cls; - enum GNUNET_DB_QueryStatus qs; - bool pending; - struct TALER_Amount fee; - - qs = TEH_plugin->lookup_transfer_by_deposit ( - TEH_plugin->cls, - &ctx->h_contract_terms, - &ctx->h_wire, - &ctx->coin_pub, - &ctx->merchant, - &pending, - &ctx->wtid, - &ctx->execution_time, - &ctx->coin_contribution, - &fee, - &ctx->kyc); - if (0 > qs) - { - if (GNUNET_DB_STATUS_HARD_ERROR == qs) - { - GNUNET_break (0); - *mhd_ret = TALER_MHD_reply_with_error ( - connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_FETCH_FAILED, - NULL); - } - return qs; - } - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) - { - *mhd_ret = TALER_MHD_reply_with_error ( - connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_EXCHANGE_DEPOSITS_GET_NOT_FOUND, - NULL); - return GNUNET_DB_STATUS_HARD_ERROR; - } - - if (0 > - TALER_amount_subtract (&ctx->coin_delta, - &ctx->coin_contribution, - &fee)) - { - GNUNET_break (0); - ctx->pending = GNUNET_SYSERR; - return qs; - } - ctx->pending = (pending) ? GNUNET_YES : GNUNET_NO; - return qs; -} - - -/** * Function called on events received from Postgres. * Wakes up long pollers. * @@ -339,55 +272,82 @@ handle_track_transaction_request ( struct DepositWtidContext *ctx) { struct MHD_Connection *connection = ctx->rc->connection; + enum GNUNET_DB_QueryStatus qs; + bool pending; + struct TALER_Amount fee; - if ( (GNUNET_TIME_absolute_is_future (ctx->timeout)) && - (NULL == ctx->eh) ) + qs = TEH_plugin->lookup_transfer_by_deposit ( + TEH_plugin->cls, + &ctx->h_contract_terms, + &ctx->h_wire, + &ctx->coin_pub, + &ctx->merchant, + &pending, + &ctx->wtid, + &ctx->execution_time, + &ctx->coin_contribution, + &fee, + &ctx->kyc, + &ctx->account_pub); + if (0 > qs) { - struct TALER_CoinDepositEventP rep = { - .header.size = htons (sizeof (rep)), - .header.type = htons (TALER_DBEVENT_EXCHANGE_DEPOSIT_STATUS_CHANGED), - .merchant_pub = ctx->merchant - }; - - ctx->eh = TEH_plugin->event_listen ( - TEH_plugin->cls, - GNUNET_TIME_absolute_get_remaining (ctx->timeout), - &rep.header, - &db_event_cb, - ctx); - GNUNET_break (NULL != ctx->eh); + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_FETCH_FAILED, + "lookup_transfer_by_deposit"); } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) { - MHD_RESULT mhd_ret; - - if (GNUNET_OK != - TEH_DB_run_transaction (connection, - "handle deposits GET", - TEH_MT_REQUEST_OTHER, - &mhd_ret, - &deposits_get_transaction, - ctx)) - return mhd_ret; + return TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_EXCHANGE_DEPOSITS_GET_NOT_FOUND, + NULL); } - if (GNUNET_SYSERR == ctx->pending) + + if (0 > + TALER_amount_subtract (&ctx->coin_delta, + &ctx->coin_contribution, + &fee)) + { + GNUNET_break (0); return TALER_MHD_reply_with_error ( connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_GENERIC_DB_INVARIANT_FAILURE, "wire fees exceed aggregate in database"); - if (GNUNET_YES == ctx->pending) + } + if (pending) { - if ( (GNUNET_TIME_absolute_is_future (ctx->timeout)) && - (GNUNET_NO == ctx->suspended) ) + if (GNUNET_TIME_absolute_is_future (ctx->timeout)) { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Suspending request handling\n"); - GNUNET_CONTAINER_DLL_insert (dwc_head, - dwc_tail, - ctx); - ctx->suspended = GNUNET_YES; - MHD_suspend_connection (connection); - return MHD_YES; + bool do_suspend = false; + switch (ctx->lpt) + { + case TALER_DGLPT_NONE: + break; + case TALER_DGLPT_KYC_REQUIRED_OR_OK: + do_suspend = ctx->kyc.ok; + break; + case TALER_DGLPT_OK: + do_suspend = true; + break; + } + if (do_suspend) + { + GNUNET_assert (GNUNET_NO == ctx->suspended); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Suspending request handling\n"); + GNUNET_CONTAINER_DLL_insert (dwc_head, + dwc_tail, + ctx); + ctx->suspended = GNUNET_YES; + MHD_suspend_connection (connection); + return MHD_YES; + } } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "KYC required with row %llu\n", @@ -401,13 +361,18 @@ handle_track_transaction_request ( NULL) : GNUNET_JSON_pack_uint64 ("requirement_row", ctx->kyc.requirement_row)), + GNUNET_JSON_pack_allow_null ( + (GNUNET_is_zero (&ctx->account_pub)) + ? GNUNET_JSON_pack_string ("account_pub", + NULL) + : GNUNET_JSON_pack_data_auto ("account_pub", + &ctx->account_pub)), GNUNET_JSON_pack_bool ("kyc_ok", ctx->kyc.ok), GNUNET_JSON_pack_timestamp ("execution_time", ctx->execution_time)); } - return reply_deposit_details (connection, - ctx); + return reply_deposit_details (ctx); } @@ -442,6 +407,7 @@ TEH_handler_deposits_get (struct TEH_RequestContext *rc, { ctx = GNUNET_new (struct DepositWtidContext); ctx->rc = rc; + ctx->lpt = TALER_DGLPT_OK; /* default */ rc->rh_ctx = ctx; rc->rh_cleaner = &dwc_cleaner; @@ -502,6 +468,31 @@ TEH_handler_deposits_get (struct TEH_RequestContext *rc, &ctx->merchant_sig); TALER_MHD_parse_request_timeout (rc->connection, &ctx->timeout); + { + uint64_t num = 0; + int val; + + TALER_MHD_parse_request_number (rc->connection, + "lpt", + &num); + val = (int) num; + if ( (val < 0) || + (val > TALER_DGLPT_MAX) ) + { + /* Protocol violation, but we can be graceful and + just ignore the long polling! */ + GNUNET_break_op (0); + val = TALER_DGLPT_NONE; + } + ctx->lpt = (enum TALER_DepositGetLongPollTarget) val; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Long polling for target %d with timeout %s\n", + val, + GNUNET_TIME_relative2s ( + GNUNET_TIME_absolute_get_remaining ( + ctx->timeout), + true)); + } TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++; { if (GNUNET_OK != @@ -519,6 +510,23 @@ TEH_handler_deposits_get (struct TEH_RequestContext *rc, NULL); } } + if ( (GNUNET_TIME_absolute_is_future (ctx->timeout)) && + (TALER_DGLPT_NONE != ctx->lpt) ) + { + struct TALER_CoinDepositEventP rep = { + .header.size = htons (sizeof (rep)), + .header.type = htons (TALER_DBEVENT_EXCHANGE_DEPOSIT_STATUS_CHANGED), + .merchant_pub = ctx->merchant + }; + + ctx->eh = TEH_plugin->event_listen ( + TEH_plugin->cls, + GNUNET_TIME_absolute_get_remaining (ctx->timeout), + &rep.header, + &db_event_cb, + ctx); + GNUNET_break (NULL != ctx->eh); + } } return handle_track_transaction_request (ctx); diff --git a/src/exchange/taler-exchange-httpd_extensions.c b/src/exchange/taler-exchange-httpd_extensions.c index e95ec56e2..607db5804 100644 --- a/src/exchange/taler-exchange-httpd_extensions.c +++ b/src/exchange/taler-exchange-httpd_extensions.c @@ -48,11 +48,11 @@ extension_update_event_cb (void *cls, const void *extra, size_t extra_size) { - (void) cls; uint32_t nbo_type; enum TALER_Extension_Type type; const struct TALER_Extension *extension; + (void) cls; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Received extensions update event\n"); @@ -67,7 +67,7 @@ extension_update_event_cb (void *cls, GNUNET_assert (NULL != extra); nbo_type = *(uint32_t *) extra; - type = (enum TALER_Extension_Type) ntohl (nbo_type); + type = (enum TALER_Extension_Type) (int) ntohl (nbo_type); /* Get the corresponding extension */ extension = TALER_extensions_get_by_type (type); diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c index 094a41b37..d9bc440e3 100644 --- a/src/exchange/taler-exchange-httpd_keys.c +++ b/src/exchange/taler-exchange-httpd_keys.c @@ -41,8 +41,10 @@ /** * When do we forcefully timeout a /keys request? + * Matches the 120s hard-coded into exchange_api_handle.c */ -#define KEYS_TIMEOUT GNUNET_TIME_UNIT_MINUTES +#define KEYS_TIMEOUT \ + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2) /** @@ -956,7 +958,7 @@ TEH_wire_update_state (void) * * @return NULL on error */ -struct WireStateHandle * +static struct WireStateHandle * get_wire_state (void) { struct WireStateHandle *old_wsh; @@ -2413,18 +2415,12 @@ create_krd (struct TEH_KeyStateHandle *ksh, GNUNET_JSON_pack_object_steal ( "currency_specification", TALER_CONFIG_currency_specs_to_json (TEH_cspec)), - GNUNET_JSON_pack_allow_null ( - TALER_JSON_pack_amount ("transaction_amount_limit", - GNUNET_OK == - TALER_amount_is_valid (&TEH_transaction_limit) - ? &TEH_transaction_limit - : NULL)), - GNUNET_JSON_pack_allow_null ( - TALER_JSON_pack_amount ("refund_amount_limit", - GNUNET_OK == - TALER_amount_is_valid (&TEH_refund_limit) - ? &TEH_refund_limit - : NULL)), + GNUNET_JSON_pack_array_incref ( + "hard_limits", + TEH_hard_limits), + GNUNET_JSON_pack_array_incref ( + "zero_limits", + TEH_zero_limits), TALER_JSON_pack_amount ("stefan_abs", &TEH_stefan_abs), TALER_JSON_pack_amount ("stefan_log", @@ -2464,6 +2460,15 @@ create_krd (struct TEH_KeyStateHandle *ksh, GNUNET_JSON_pack_array_steal ( "wallet_balance_limit_without_kyc", TALER_KYCLOGIC_get_wallet_thresholds ())), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("shopping_url", + TEH_shopping_url)), + GNUNET_JSON_pack_allow_null ( + TALER_amount_is_zero (&TEH_tiny_amount) + ? GNUNET_JSON_pack_string ("dummy", + NULL) + : TALER_JSON_pack_amount ("tiny_amount", + &TEH_tiny_amount)), GNUNET_JSON_pack_data_auto ("exchange_pub", &exchange_pub), GNUNET_JSON_pack_data_auto ("exchange_sig", diff --git a/src/exchange/taler-exchange-httpd_kyc-check.c b/src/exchange/taler-exchange-httpd_kyc-check.c index 78073d83b..96b3d12f3 100644 --- a/src/exchange/taler-exchange-httpd_kyc-check.c +++ b/src/exchange/taler-exchange-httpd_kyc-check.c @@ -30,10 +30,10 @@ #include "taler_signatures.h" #include "taler_dbevents.h" #include "taler-exchange-httpd_keys.h" +#include "taler-exchange-httpd_kyc-check.h" #include "taler-exchange-httpd_kyc-wallet.h" #include "taler-exchange-httpd_responses.h" - /** * Reserve GET request that is long-polling. */ @@ -61,9 +61,9 @@ struct KycPoller struct GNUNET_DB_EventHandler *eh; /** - * Row of the requirement being checked. + * Account for which we perform the KYC check. */ - uint64_t requirement_row; + struct TALER_PaytoHashP h_payto; /** * When will this request time out? @@ -77,6 +77,11 @@ struct KycPoller union TALER_AccountSignatureP account_sig; /** + * What are we long-polling for (if anything)? + */ + enum TALER_EXCHANGE_KycLongPollTarget lpt; + + /** * True if we are still suspended. */ bool suspended; @@ -191,6 +196,7 @@ TEH_handler_kyc_check ( struct TALER_AccountAccessTokenP access_token; bool aml_review; bool kyc_required; + bool access_ok = false; if (NULL == kyp) { @@ -201,24 +207,18 @@ TEH_handler_kyc_check ( rc->rh_ctx = kyp; rc->rh_cleaner = &kyp_cleanup; + if (GNUNET_OK != + GNUNET_STRINGS_string_to_data (args[0], + strlen (args[0]), + &kyp->h_payto, + sizeof (kyp->h_payto))) { - unsigned long long requirement_row; - char dummy; - - if (1 != - sscanf (args[0], - "%llu%c", - &requirement_row, - &dummy)) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error ( - rc->connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "requirement_row"); - } - kyp->requirement_row = (uint64_t) requirement_row; + GNUNET_break_op (0); + return TALER_MHD_reply_with_error ( + rc->connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PATH_SEGMENT_MALFORMED, + "h_payto"); } TALER_MHD_parse_request_header_auto ( @@ -228,7 +228,50 @@ TEH_handler_kyc_check ( sig_required); TALER_MHD_parse_request_timeout (rc->connection, &kyp->timeout); - } + { + uint64_t num = 0; + int val; + + TALER_MHD_parse_request_number (rc->connection, + "lpt", + &num); + val = (int) num; + if ( (val < 0) || + (val > TALER_EXCHANGE_KLPT_MAX) ) + { + /* Protocol violation, but we can be graceful and + just ignore the long polling! */ + GNUNET_break_op (0); + val = TALER_EXCHANGE_KLPT_NONE; + } + kyp->lpt = (enum TALER_EXCHANGE_KycLongPollTarget) val; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Long polling for target %d with timeout %s\n", + val, + GNUNET_TIME_relative2s ( + GNUNET_TIME_absolute_get_remaining ( + kyp->timeout), + true)); + } + /* long polling needed? */ + if (GNUNET_TIME_absolute_is_future (kyp->timeout)) + { + struct TALER_KycCompletedEventP rep = { + .header.size = htons (sizeof (rep)), + .header.type = htons (TALER_DBEVENT_EXCHANGE_KYC_COMPLETED), + .h_payto = kyp->h_payto + }; + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Starting DB event listening\n"); + kyp->eh = TEH_plugin->event_listen ( + TEH_plugin->cls, + GNUNET_TIME_absolute_get_remaining (kyp->timeout), + &rep.header, + &db_event_cb, + rc); + } + } /* end initialization */ if (! TEH_enable_kyc) { @@ -244,13 +287,14 @@ TEH_handler_kyc_check ( { enum GNUNET_DB_QueryStatus qs; + bool do_suspend; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Looking up KYC requirements by row %llu\n", - (unsigned long long) kyp->requirement_row); + "Looking up KYC requirements for account %s\n", + TALER_B2S (&kyp->h_payto)); qs = TEH_plugin->lookup_kyc_requirement_by_row ( TEH_plugin->cls, - kyp->requirement_row, + &kyp->h_payto, &account_pub, &reserve_pub.reserve_pub, &access_token, @@ -265,9 +309,75 @@ TEH_handler_kyc_check ( TALER_EC_GENERIC_DB_STORE_FAILED, "lookup_kyc_requirement_by_row"); } + do_suspend = false; if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) { - GNUNET_break_op (0); + /* account unknown */ + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Account unknown!\n"); + if ( (TALER_EXCHANGE_KLPT_NONE != kyp->lpt) && + (TALER_EXCHANGE_KLPT_KYC_OK != kyp->lpt) && + (GNUNET_TIME_absolute_is_future (kyp->timeout)) ) + { + do_suspend = true; + access_ok = true; /* for now */ + } + } + else + { + access_ok = + ( (! GNUNET_is_zero (&account_pub) && + (GNUNET_OK == + TALER_account_kyc_auth_verify (&account_pub, + &kyp->account_sig)) ) || + (! GNUNET_is_zero (&reserve_pub) && + (GNUNET_OK == + TALER_account_kyc_auth_verify (&reserve_pub, + &kyp->account_sig)) ) ); + if (GNUNET_TIME_absolute_is_future (kyp->timeout)) + { + switch (kyp->lpt) + { + case TALER_EXCHANGE_KLPT_NONE: + break; + case TALER_EXCHANGE_KLPT_KYC_AUTH_TRANSFER: + if (! access_ok) + do_suspend = true; + break; + case TALER_EXCHANGE_KLPT_INVESTIGATION_DONE: + if (! aml_review) + do_suspend = true; + break; + case TALER_EXCHANGE_KLPT_KYC_OK: + if (kyc_required) + do_suspend = true; + break; + } + } + } + + if (do_suspend && + (access_ok || + (TALER_EXCHANGE_KLPT_KYC_AUTH_TRANSFER == kyp->lpt) ) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Suspending HTTP request on timeout (%s) for %d\n", + GNUNET_TIME_relative2s (GNUNET_TIME_absolute_get_remaining ( + kyp->timeout), + true), + (int) kyp->lpt); + GNUNET_assert (NULL != kyp->eh); + kyp->suspended = true; + GNUNET_CONTAINER_DLL_insert (kyp_head, + kyp_tail, + kyp); + MHD_suspend_connection (kyp->connection); + return MHD_YES; + } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Returning account unknown\n"); return TALER_MHD_reply_with_error ( rc->connection, MHD_HTTP_NOT_FOUND, @@ -276,18 +386,8 @@ TEH_handler_kyc_check ( } } - if ( (GNUNET_is_zero (&account_pub) || - (GNUNET_OK != - TALER_account_kyc_auth_verify (&account_pub, - &kyp->account_sig)) ) && - (GNUNET_is_zero (&reserve_pub) || - (GNUNET_OK != - TALER_account_kyc_auth_verify (&reserve_pub, - &kyp->account_sig)) ) ) + if (! access_ok) { - char *diag; - MHD_RESULT mret; - json_decref (jrules); jrules = NULL; if (GNUNET_is_zero (&account_pub)) @@ -299,15 +399,15 @@ TEH_handler_kyc_check ( TALER_EC_EXCHANGE_KYC_CHECK_AUTHORIZATION_KEY_UNKNOWN, NULL); } - diag = GNUNET_STRINGS_data_to_string_alloc (&account_pub, - sizeof (account_pub)); - mret = TALER_MHD_reply_with_error ( + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Returning authorization failed\n"); + return TALER_MHD_REPLY_JSON_PACK ( rc->connection, MHD_HTTP_FORBIDDEN, - TALER_EC_EXCHANGE_KYC_CHECK_AUTHORIZATION_FAILED, - diag); - GNUNET_free (diag); - return mret; + TALER_JSON_pack_ec ( + TALER_EC_EXCHANGE_KYC_CHECK_AUTHORIZATION_FAILED), + GNUNET_JSON_pack_data_auto ("expected_account_pub", + &account_pub)); } jlimits = TALER_KYCLOGIC_rules_to_limits (jrules); @@ -325,71 +425,14 @@ TEH_handler_kyc_check ( json_decref (jrules); jrules = NULL; - /* long polling for positive result? */ - if (kyc_required && - GNUNET_TIME_absolute_is_future (kyp->timeout)) - { - enum GNUNET_DB_QueryStatus qs; - struct TALER_KycCompletedEventP rep = { - .header.size = htons (sizeof (rep)), - .header.type = htons (TALER_DBEVENT_EXCHANGE_KYC_COMPLETED), - }; - - json_decref (jlimits); - if (NULL == kyp->eh) - { - /* FIXME-Performance: consider modifying lookup_kyc_requirement_by_row - to immediately return h_payto as well... */ - qs = TEH_plugin->lookup_h_payto_by_access_token ( - TEH_plugin->cls, - &access_token, - &rep.h_payto); - if (qs < 0) - { - GNUNET_break (0); - return TALER_MHD_reply_with_ec ( - rc->connection, - TALER_EC_GENERIC_DB_FETCH_FAILED, - "lookup_h_payto_by_access_token"); - } - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Starting DB event listening\n"); - kyp->eh = TEH_plugin->event_listen ( - TEH_plugin->cls, - GNUNET_TIME_absolute_get_remaining (kyp->timeout), - &rep.header, - &db_event_cb, - rc); - /* goes again *immediately* (without suspending) - now that long-poller is in place; we will suspend - in the *next* iteration. */ - return MHD_YES; - } - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Suspending HTTP request on timeout (%s) now...\n", - GNUNET_TIME_relative2s (GNUNET_TIME_absolute_get_remaining ( - kyp->timeout), - true)); - GNUNET_assert (NULL != kyp->eh); - kyp->suspended = true; - GNUNET_CONTAINER_DLL_insert (kyp_head, - kyp_tail, - kyp); - MHD_suspend_connection (kyp->connection); - return MHD_YES; - } - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Returning KYC %s for row %llu\n", - kyc_required ? "required" : "optional", - (unsigned long long) kyp->requirement_row); - + "Returning KYC %s\n", + kyc_required ? "required" : "optional"); return TALER_MHD_REPLY_JSON_PACK ( rc->connection, kyc_required - ? MHD_HTTP_ACCEPTED - : MHD_HTTP_OK, + ? MHD_HTTP_ACCEPTED + : MHD_HTTP_OK, GNUNET_JSON_pack_bool ("aml_review", aml_review), GNUNET_JSON_pack_data_auto ("access_token", diff --git a/src/exchange/taler-exchange-httpd_kyc-check.h b/src/exchange/taler-exchange-httpd_kyc-check.h index f1f2c9e7d..147aa5888 100644 --- a/src/exchange/taler-exchange-httpd_kyc-check.h +++ b/src/exchange/taler-exchange-httpd_kyc-check.h @@ -36,7 +36,7 @@ MHD_RESULT TEH_handler_kyc_check ( struct TEH_RequestContext *rc, - const char *const args[]); + const char *const args[1]); /** diff --git a/src/exchange/taler-exchange-httpd_kyc-info.c b/src/exchange/taler-exchange-httpd_kyc-info.c index 88da07de3..681d0321b 100644 --- a/src/exchange/taler-exchange-httpd_kyc-info.c +++ b/src/exchange/taler-exchange-httpd_kyc-info.c @@ -30,7 +30,7 @@ #include "taler_signatures.h" #include "taler_dbevents.h" #include "taler-exchange-httpd_keys.h" -#include "taler-exchange-httpd_kyc-wallet.h" +#include "taler-exchange-httpd_kyc-info.h" #include "taler-exchange-httpd_responses.h" @@ -64,7 +64,13 @@ struct KycPoller * #MHD_HTTP_HEADER_IF_NONE_MATCH Etag value sent by the client. 0 for none * (or malformed). */ - uint64_t etag_in; + uint64_t etag_outcome_in; + + /** + * #MHD_HTTP_HEADER_IF_NONE_MATCH Etag value sent by the client. 0 for none + * (or malformed). + */ + uint64_t etag_measure_in; /** * When will this request time out? @@ -78,6 +84,11 @@ struct KycPoller struct TALER_AccountAccessTokenP access_token; /** + * Payto hash of the account matching @a access_token. + */ + struct TALER_PaytoHashP h_payto; + + /** * True if we are still suspended. */ bool suspended; @@ -198,16 +209,20 @@ add_response_headers (void *cls, * the LegitimizationMeasures. * * @param[in,out] kyp request to reply on - * @param legitimization_measure_row_id etag to set for the response - * @param jmeasures measures to encode + * @param legitimization_measure_row_id part of etag to set for the response + * @param legitimization_outcome_row_id part of etag to set for the response + * @param jmeasures a `LegitimizationMeasures` object to encode + * @param jvoluntary array of voluntary measures to encode, can be NULL * @return MHD status code */ static MHD_RESULT generate_reply (struct KycPoller *kyp, uint64_t legitimization_measure_row_id, - const json_t *jmeasures) + uint64_t legitimization_outcome_row_id, + const json_t *jmeasures, + const json_t *jvoluntary) { - const json_t *measures; + const json_t *measures; /* array of MeasureInformation */ bool is_and_combinator = false; bool verboten; struct GNUNET_JSON_Specification spec[] = { @@ -221,18 +236,18 @@ generate_reply (struct KycPoller *kyp, &measures), GNUNET_JSON_spec_end () }; - enum GNUNET_GenericReturnValue res; + enum GNUNET_GenericReturnValue ret; const char *ename; unsigned int eline; json_t *kris; size_t i; - json_t *mi; + json_t *mi; /* a MeasureInformation object */ - res = GNUNET_JSON_parse (jmeasures, + ret = GNUNET_JSON_parse (jmeasures, spec, &ename, &eline); - if (GNUNET_OK != res) + if (GNUNET_OK != ret) { GNUNET_break (0); return TALER_MHD_reply_with_ec ( @@ -246,20 +261,25 @@ generate_reply (struct KycPoller *kyp, { const char *check_name; const char *prog_name; + const json_t *context = NULL; struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_string ("check_name", &check_name), GNUNET_JSON_spec_string ("prog_name", &prog_name), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_object_const ("context", + &context), + NULL), GNUNET_JSON_spec_end () }; json_t *kri; - res = GNUNET_JSON_parse (mi, + ret = GNUNET_JSON_parse (mi, ispec, &ename, &eline); - if (GNUNET_OK != res) + if (GNUNET_OK != ret) { GNUNET_break (0); json_decref (kris); @@ -271,6 +291,7 @@ generate_reply (struct KycPoller *kyp, kri = TALER_KYCLOGIC_measure_to_requirement ( check_name, prog_name, + context, &kyp->access_token, i, legitimization_measure_row_id); @@ -289,23 +310,24 @@ generate_reply (struct KycPoller *kyp, } { - char etags[64]; + char etags[128]; struct MHD_Response *resp; MHD_RESULT res; GNUNET_snprintf (etags, sizeof (etags), - "\"%llu\"", - (unsigned long long) legitimization_measure_row_id); + "\"%llu-%llu\"", + (unsigned long long) legitimization_measure_row_id, + (unsigned long long) legitimization_outcome_row_id); resp = TALER_MHD_MAKE_JSON_PACK ( GNUNET_JSON_pack_array_steal ("requirements", kris), GNUNET_JSON_pack_bool ("is_and_combinator", is_and_combinator), GNUNET_JSON_pack_allow_null ( - /* TODO: support vATTEST-9048 */ - GNUNET_JSON_pack_object_steal ("voluntary_checks", - NULL))); + GNUNET_JSON_pack_array_incref ( + "voluntary_measures", + (json_t *) jvoluntary))); GNUNET_break (MHD_YES == MHD_add_response_header (resp, MHD_HTTP_HEADER_ETAG, @@ -322,6 +344,51 @@ generate_reply (struct KycPoller *kyp, } +/** + * Check if measures contain an instant + * measure. + * + * @param jmeasures measures JSON object + * @returns true if @a jmeasures contains an instant measure + */ +bool +contains_instant_measure (const json_t *jmeasures) +{ + size_t i; + json_t *mi; /* a MeasureInformation object */ + const char *ename; + unsigned int eline; + enum GNUNET_GenericReturnValue ret; + + json_array_foreach ((json_t *) jmeasures, i, mi) + { + const char *check_name; + + struct GNUNET_JSON_Specification ispec[] = { + GNUNET_JSON_spec_string ("check_name", + &check_name), + GNUNET_JSON_spec_end () + }; + + ret = GNUNET_JSON_parse (mi, + ispec, + &ename, + &eline); + if (GNUNET_OK != ret) + { + GNUNET_break (0); + continue; + } + if (0 == strcasecmp (check_name, "SKIP")) + { + return true; + } + } + + return false; +} + + MHD_RESULT TEH_handler_kyc_info ( struct TEH_RequestContext *rc, @@ -331,7 +398,11 @@ TEH_handler_kyc_info ( MHD_RESULT res; enum GNUNET_DB_QueryStatus qs; uint64_t legitimization_measure_last_row; - json_t *jmeasures; + uint64_t legitimization_outcome_last_row; + json_t *jmeasures = NULL; + json_t *jvoluntary = NULL; + json_t *jnew_rules; + struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs; if (NULL == kyp) { @@ -368,11 +439,13 @@ TEH_handler_kyc_info ( if (NULL != etags) { char dummy; - unsigned long long ev; + unsigned long long ev1; + unsigned long long ev2; - if (1 != sscanf (etags, - "\"%llu\"%c", - &ev, + if (2 != sscanf (etags, + "\"%llu-%llu\"%c", + &ev1, + &ev2, &dummy)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -382,24 +455,17 @@ TEH_handler_kyc_info ( } else { - kyp->etag_in = (uint64_t) ev; + kyp->etag_measure_in = (uint64_t) ev1; + kyp->etag_outcome_in = (uint64_t) ev2; } } } /* etag */ - } /* one-time initialization */ - - if ( (NULL == kyp->eh) && - GNUNET_TIME_absolute_is_future (kyp->timeout) ) - { - struct TALER_KycCompletedEventP rep = { - .header.size = htons (sizeof (rep)), - .header.type = htons (TALER_DBEVENT_EXCHANGE_KYC_COMPLETED) - }; + /* Check access token */ qs = TEH_plugin->lookup_h_payto_by_access_token ( TEH_plugin->cls, &kyp->access_token, - &rep.h_payto); + &kyp->h_payto); if (qs < 0) { GNUNET_break (0); @@ -408,16 +474,63 @@ TEH_handler_kyc_info ( TALER_EC_GENERIC_DB_FETCH_FAILED, "lookup_h_payto_by_access_token"); } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + { + GNUNET_break_op (0); + return TALER_MHD_REPLY_JSON_PACK ( + rc->connection, + MHD_HTTP_FORBIDDEN, + TALER_JSON_pack_ec ( + TALER_EC_EXCHANGE_KYC_INFO_AUTHORIZATION_FAILED)); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Starting DB event listening\n"); - kyp->eh = TEH_plugin->event_listen ( - TEH_plugin->cls, - GNUNET_TIME_absolute_get_remaining (kyp->timeout), - &rep.header, - &db_event_cb, - rc); + } + + if (GNUNET_TIME_absolute_is_future (kyp->timeout)) + { + struct TALER_KycCompletedEventP rep = { + .header.size = htons (sizeof (rep)), + .header.type = htons (TALER_DBEVENT_EXCHANGE_KYC_COMPLETED), + .h_payto = kyp->h_payto + }; + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Starting DB event listening\n"); + kyp->eh = TEH_plugin->event_listen ( + TEH_plugin->cls, + GNUNET_TIME_absolute_get_remaining (kyp->timeout), + &rep.header, + &db_event_cb, + rc); + } + } /* end of one-time initialization */ + + qs = TEH_plugin->lookup_rules_by_access_token ( + TEH_plugin->cls, + &kyp->h_payto, + &jnew_rules, + &legitimization_outcome_last_row); + if (qs < 0) + { + GNUNET_break (0); + return TALER_MHD_reply_with_ec ( + rc->connection, + TALER_EC_GENERIC_DB_FETCH_FAILED, + "lookup_rules_by_access_token"); + } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + { + /* Nothing was triggered, return the measures + that apply for any amount. */ + lrs = NULL; + } + else + { + lrs = TALER_KYCLOGIC_rules_parse (jnew_rules); + GNUNET_break (NULL != lrs); + json_decref (jnew_rules); } + jvoluntary + = TALER_KYCLOGIC_voluntary_measures (lrs); qs = TEH_plugin->lookup_kyc_status_by_token ( TEH_plugin->cls, @@ -427,6 +540,7 @@ TEH_handler_kyc_info ( if (qs < 0) { GNUNET_break (0); + TALER_KYCLOGIC_rules_free (lrs); return TALER_MHD_reply_with_ec ( rc->connection, TALER_EC_GENERIC_DB_FETCH_FAILED, @@ -434,17 +548,39 @@ TEH_handler_kyc_info ( } if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "No KYC requirement open\n"); - return TALER_MHD_REPLY_JSON_PACK ( - rc->connection, - MHD_HTTP_OK, - GNUNET_JSON_pack_allow_null ( - /* TODO: support vATTEST-9048 */ - GNUNET_JSON_pack_object_steal ("voluntary_checks", - NULL))); + jmeasures + = TALER_KYCLOGIC_zero_measures (lrs); + if (NULL == jmeasures) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "No KYC requirement open\n"); + TALER_KYCLOGIC_rules_free (lrs); + return TALER_MHD_REPLY_JSON_PACK ( + rc->connection, + MHD_HTTP_OK, + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_array_steal ("voluntary_measures", + jvoluntary))); + } + + qs = TEH_plugin->insert_active_legitimization_measure ( + TEH_plugin->cls, + &kyp->access_token, + jmeasures, + &legitimization_measure_last_row); + if (qs < 0) + { + GNUNET_break (0); + TALER_KYCLOGIC_rules_free (lrs); + return TALER_MHD_reply_with_ec ( + rc->connection, + TALER_EC_GENERIC_DB_STORE_FAILED, + "insert_active_legitimization_measure"); + } } - if ( (legitimization_measure_last_row == kyp->etag_in) && + TALER_KYCLOGIC_rules_free (lrs); + if ( (legitimization_measure_last_row == kyp->etag_measure_in) && + (legitimization_outcome_last_row == kyp->etag_outcome_in) && GNUNET_TIME_absolute_is_future (kyp->timeout) ) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, @@ -461,15 +597,29 @@ TEH_handler_kyc_info ( MHD_suspend_connection (rc->connection); return MHD_YES; } - if (legitimization_measure_last_row == kyp->etag_in) + if (contains_instant_measure (jmeasures)) + { + json_decref (jmeasures); + json_decref (jvoluntary); + return TALER_MHD_reply_with_ec ( + rc->connection, + TALER_EC_EXCHANGE_KYC_INFO_BUSY, + "waiting for KYC program"); + } + if ( (legitimization_measure_last_row == + kyp->etag_measure_in) && + (legitimization_outcome_last_row == + kyp->etag_outcome_in) ) { - char etags[64]; + char etags[128]; json_decref (jmeasures); + json_decref (jvoluntary); GNUNET_snprintf (etags, sizeof (etags), - "\"%llu\"", - (unsigned long long) legitimization_measure_last_row); + "\"%llu-%llu\"", + (unsigned long long) legitimization_measure_last_row, + (unsigned long long) legitimization_outcome_last_row); return TEH_RESPONSE_reply_not_modified ( rc->connection, etags, @@ -478,8 +628,11 @@ TEH_handler_kyc_info ( } res = generate_reply (kyp, legitimization_measure_last_row, - jmeasures); + legitimization_outcome_last_row, + jmeasures, + jvoluntary); json_decref (jmeasures); + json_decref (jvoluntary); return res; } diff --git a/src/exchange/taler-exchange-httpd_kyc-proof.c b/src/exchange/taler-exchange-httpd_kyc-proof.c index 657c28c6a..1ba978a3a 100644 --- a/src/exchange/taler-exchange-httpd_kyc-proof.c +++ b/src/exchange/taler-exchange-httpd_kyc-proof.c @@ -198,7 +198,7 @@ proof_finish ( * @param message extended message to return * @return MHD response object */ -struct MHD_Response * +static struct MHD_Response * make_html_error (struct MHD_Connection *connection, const char *template, unsigned int *http_status, diff --git a/src/exchange/taler-exchange-httpd_kyc-start.c b/src/exchange/taler-exchange-httpd_kyc-start.c index 1f894d45e..f49f07e8a 100644 --- a/src/exchange/taler-exchange-httpd_kyc-start.c +++ b/src/exchange/taler-exchange-httpd_kyc-start.c @@ -30,7 +30,7 @@ #include "taler_signatures.h" #include "taler_dbevents.h" #include "taler-exchange-httpd_keys.h" -#include "taler-exchange-httpd_kyc-wallet.h" +#include "taler-exchange-httpd_kyc-start.h" #include "taler-exchange-httpd_responses.h" @@ -273,8 +273,6 @@ TEH_handler_kyc_start ( const struct TALER_KYCLOGIC_KycProvider *provider; struct TALER_KYCLOGIC_ProviderDetails *pd; bool is_finished; - size_t enc_len; - void *enc = NULL; kyp = GNUNET_new (struct KycPoller); kyp->connection = rc->connection; @@ -329,9 +327,7 @@ TEH_handler_kyc_start ( &kyp->access_token, &kyp->h_payto, &kyp->jmeasures, - &is_finished, - &enc_len, - &enc); + &is_finished); if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); @@ -349,14 +345,13 @@ TEH_handler_kyc_start ( TALER_EC_GENERIC_ENDPOINT_UNKNOWN, rc->url); } - GNUNET_free (enc); if (is_finished) { GNUNET_break_op (0); return TALER_MHD_reply_with_error ( rc->connection, MHD_HTTP_CONFLICT, - -1, // FIXME: TALER_EC_..._ALREADY_FINISHED + TALER_EC_EXCHANGE_KYC_FORM_ALREADY_UPLOADED, rc->url); } diff --git a/src/exchange/taler-exchange-httpd_kyc-start.h b/src/exchange/taler-exchange-httpd_kyc-start.h index 99d5a7891..f6e8013f9 100644 --- a/src/exchange/taler-exchange-httpd_kyc-start.h +++ b/src/exchange/taler-exchange-httpd_kyc-start.h @@ -26,18 +26,25 @@ /** + * Resume suspended requests for /kyc-start. + */ +void +TEH_kyc_start_cleanup (void); + + +/** * Handle a "/kyc-start" request. * * @param rc request to handle * @param root uploaded JSON data (empty by current API) - * @param args empty array + * @param args array with the ID * @return MHD result code */ MHD_RESULT TEH_handler_kyc_start ( struct TEH_RequestContext *rc, const json_t *root, - const char *const args[]); + const char *const args[1]); #endif diff --git a/src/exchange/taler-exchange-httpd_kyc-upload.c b/src/exchange/taler-exchange-httpd_kyc-upload.c index 9dd16b0cb..2841b94d0 100644 --- a/src/exchange/taler-exchange-httpd_kyc-upload.c +++ b/src/exchange/taler-exchange-httpd_kyc-upload.c @@ -465,15 +465,27 @@ TEH_handler_kyc_upload ( const char *error_message; enum TALER_ErrorCode ec; - qs = TEH_plugin->lookup_pending_legitimization ( + qs = TEH_plugin->lookup_completed_legitimization ( TEH_plugin->cls, uc->legitimization_measure_serial_id, + uc->measure_index, &uc->access_token, &h_payto, &jmeasures, &is_finished, &enc_attributes_len, &enc_attributes); + /* FIXME: not exactly elegant, should eventually + modify lookup_completed_legitimization to + return something if we are purely pending? */ + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + qs = TEH_plugin->lookup_pending_legitimization ( + TEH_plugin->cls, + uc->legitimization_measure_serial_id, + &uc->access_token, + &h_payto, + &jmeasures, + &is_finished); if (qs < 0) { GNUNET_break (0); @@ -567,9 +579,8 @@ TEH_handler_kyc_upload ( } empty_response - = MHD_create_response_from_buffer (0, - "", - MHD_RESPMEM_PERSISTENT); + = MHD_create_response_from_buffer_static (0, + ""); uc->kat = TEH_kyc_finished ( &rc->async_scope_id, legi_process_row, diff --git a/src/exchange/taler-exchange-httpd_kyc-wallet.c b/src/exchange/taler-exchange-httpd_kyc-wallet.c index 4945881b5..de93c74ef 100644 --- a/src/exchange/taler-exchange-httpd_kyc-wallet.c +++ b/src/exchange/taler-exchange-httpd_kyc-wallet.c @@ -30,7 +30,6 @@ #include "taler-exchange-httpd_common_kyc.h" #include "taler-exchange-httpd_kyc-wallet.h" #include "taler-exchange-httpd_responses.h" -#include "taler-exchange-httpd_withdraw.h" /** @@ -321,7 +320,8 @@ TEH_handler_kyc_wallet ( } return TEH_RESPONSE_reply_kyc_required (rc->connection, &krc->h_payto, - &krc->kyc); + &krc->kyc, + false); } diff --git a/src/exchange/taler-exchange-httpd_purses_deposit.c b/src/exchange/taler-exchange-httpd_purses_deposit.c index d518e6250..d3bfe201e 100644 --- a/src/exchange/taler-exchange-httpd_purses_deposit.c +++ b/src/exchange/taler-exchange-httpd_purses_deposit.c @@ -359,8 +359,9 @@ TEH_handler_purses_deposit ( GNUNET_assert (GNUNET_OK == TALER_amount_set_zero (TEH_currency, &pcc.deposit_total)); - pcc.num_coins = json_array_size (deposits); + pcc.num_coins = (unsigned int) json_array_size (deposits); if ( (0 == pcc.num_coins) || + (((size_t) pcc.num_coins) != json_array_size (deposits)) || (pcc.num_coins > TALER_MAX_FRESH_COINS) ) { GNUNET_break_op (0); diff --git a/src/exchange/taler-exchange-httpd_purses_get.c b/src/exchange/taler-exchange-httpd_purses_get.c index 22328fe09..b6e5673fa 100644 --- a/src/exchange/taler-exchange-httpd_purses_get.c +++ b/src/exchange/taler-exchange-httpd_purses_get.c @@ -188,11 +188,6 @@ db_event_cb (void *cls, (void) extra; (void) extra_size; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Waking up on %p - %p - %s\n", - rc, - gc, - gc->suspended ? "suspended" : "active"); if (NULL == gc) return; /* event triggered while main transaction was still running */ @@ -202,7 +197,10 @@ db_event_cb (void *cls, GNUNET_async_scope_enter (&rc->async_scope_id, &old_scope); GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Resuming from long-polling on purse\n"); + "Waking up on %p - %p - %s\n", + rc, + gc, + gc->suspended ? "suspended" : "active"); TEH_check_invariants (); GNUNET_CONTAINER_DLL_remove (gc_head, gc_tail, @@ -271,8 +269,11 @@ TEH_handler_purses_get (struct TEH_RequestContext *rc, }; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Starting DB event listening on purse %s\n", - TALER_B2S (&gc->purse_pub)); + "Starting DB event listening on purse %s (%s)\n", + TALER_B2S (&gc->purse_pub), + gc->wait_for_merge + ? "waiting for merge" + : "waiting for deposit"); gc->eh = TEH_plugin->event_listen ( TEH_plugin->cls, GNUNET_TIME_absolute_get_remaining (gc->timeout), @@ -315,6 +316,11 @@ TEH_handler_purses_get (struct TEH_RequestContext *rc, &gc->merge_timestamp, &purse_deleted, &purse_refunded); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "select_purse %s returned %d (%s)\n", + args[0], + (int) qs, + GNUNET_TIME_timestamp2s (gc->merge_timestamp)); switch (qs) { case GNUNET_DB_STATUS_HARD_ERROR: @@ -347,14 +353,20 @@ TEH_handler_purses_get (struct TEH_RequestContext *rc, MHD_HTTP_GONE, purse_deleted ? TALER_EC_EXCHANGE_GENERIC_PURSE_DELETED - : TALER_EC_EXCHANGE_GENERIC_PURSE_EXPIRED, + : TALER_EC_EXCHANGE_GENERIC_PURSE_EXPIRED + , GNUNET_TIME_timestamp2s ( gc->purse_expiration)); } GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Deposited amount is %s\n", - TALER_amount2s (&gc->deposited)); + "Deposited amount is %s (%d/%d/%d)\n", + TALER_amount2s (&gc->deposited), + GNUNET_TIME_absolute_is_future (gc->timeout), + GNUNET_TIME_absolute_is_never (gc->merge_timestamp.abs_time), + (0 < + TALER_amount_cmp (&gc->amount, + &gc->deposited))); if (GNUNET_TIME_absolute_is_future (gc->timeout) && ( ((gc->wait_for_merge) && GNUNET_TIME_absolute_is_never (gc->merge_timestamp.abs_time)) || diff --git a/src/exchange/taler-exchange-httpd_purses_merge.c b/src/exchange/taler-exchange-httpd_purses_merge.c index 86c0414f7..7c542242c 100644 --- a/src/exchange/taler-exchange-httpd_purses_merge.c +++ b/src/exchange/taler-exchange-httpd_purses_merge.c @@ -33,7 +33,6 @@ #include "taler-exchange-httpd_common_kyc.h" #include "taler-exchange-httpd_purses_merge.h" #include "taler-exchange-httpd_responses.h" -#include "taler-exchange-httpd_withdraw.h" #include "taler_exchangedb_lib.h" #include "taler-exchange-httpd_keys.h" @@ -763,9 +762,11 @@ TEH_handler_purses_merge ( pmc->response); } if (! pmc->kyc.ok) - return TEH_RESPONSE_reply_kyc_required (rc->connection, - &pmc->h_payto, - &pmc->kyc); + return TEH_RESPONSE_reply_kyc_required ( + rc->connection, + &pmc->h_payto, + &pmc->kyc, + false); /* execute merge transaction */ { diff --git a/src/exchange/taler-exchange-httpd_refreshes_reveal.c b/src/exchange/taler-exchange-httpd_refreshes_reveal.c index 5630051cf..530cce5a7 100644 --- a/src/exchange/taler-exchange-httpd_refreshes_reveal.c +++ b/src/exchange/taler-exchange-httpd_refreshes_reveal.c @@ -445,7 +445,6 @@ resolve_refreshes_reveal_denominations ( MHD_RESULT ret; struct TEH_KeyStateHandle *ksh; uint64_t melt_serial_id; - enum GNUNET_DB_QueryStatus qs; memset (dks, 0, sizeof (dks)); memset (rrcs, 0, sizeof (rrcs)); @@ -781,77 +780,80 @@ clean_age: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Signatures ready, starting DB interaction\n"); - - for (unsigned int r = 0; r<MAX_TRANSACTION_COMMIT_RETRIES; r++) { - bool changed; + enum GNUNET_DB_QueryStatus qs; - /* Persist operation result in DB */ - if (GNUNET_OK != - TEH_plugin->start (TEH_plugin->cls, - "insert_refresh_reveal batch")) + for (unsigned int r = 0; r<MAX_TRANSACTION_COMMIT_RETRIES; r++) { - GNUNET_break (0); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_START_FAILED, - NULL); - goto cleanup; - } + bool changed; - qs = TEH_plugin->insert_refresh_reveal ( - TEH_plugin->cls, - melt_serial_id, - num_fresh_coins, - rrcs, - TALER_CNC_KAPPA - 1, - rctx->transfer_privs, - &rctx->gamma_tp); - if (GNUNET_DB_STATUS_SOFT_ERROR == qs) - { - TEH_plugin->rollback (TEH_plugin->cls); - continue; - } - /* 0 == qs is ok, as we did not check for repeated requests */ - if (GNUNET_DB_STATUS_HARD_ERROR == qs) - { - GNUNET_break (0); + /* Persist operation result in DB */ + if (GNUNET_OK != + TEH_plugin->start (TEH_plugin->cls, + "insert_refresh_reveal batch")) + { + GNUNET_break (0); + ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_START_FAILED, + NULL); + goto cleanup; + } + + qs = TEH_plugin->insert_refresh_reveal ( + TEH_plugin->cls, + melt_serial_id, + num_fresh_coins, + rrcs, + TALER_CNC_KAPPA - 1, + rctx->transfer_privs, + &rctx->gamma_tp); + if (GNUNET_DB_STATUS_SOFT_ERROR == qs) + { + TEH_plugin->rollback (TEH_plugin->cls); + continue; + } + /* 0 == qs is ok, as we did not check for repeated requests */ + if (GNUNET_DB_STATUS_HARD_ERROR == qs) + { + GNUNET_break (0); + TEH_plugin->rollback (TEH_plugin->cls); + ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_STORE_FAILED, + "insert_refresh_reveal"); + goto cleanup; + } + changed = (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs); + qs = TEH_plugin->commit (TEH_plugin->cls); + if (qs >= 0) + { + if (changed) + TEH_METRICS_num_success[TEH_MT_SUCCESS_REFRESH_REVEAL]++; + break; /* success */ + } + if (GNUNET_DB_STATUS_HARD_ERROR == qs) + { + GNUNET_break (0); + TEH_plugin->rollback (TEH_plugin->cls); + ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_COMMIT_FAILED, + NULL); + goto cleanup; + } TEH_plugin->rollback (TEH_plugin->cls); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "insert_refresh_reveal"); - goto cleanup; - } - changed = (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs); - qs = TEH_plugin->commit (TEH_plugin->cls); - if (qs >= 0) - { - if (changed) - TEH_METRICS_num_success[TEH_MT_SUCCESS_REFRESH_REVEAL]++; - break; /* success */ } - if (GNUNET_DB_STATUS_HARD_ERROR == qs) + if (GNUNET_DB_STATUS_SOFT_ERROR == qs) { GNUNET_break (0); TEH_plugin->rollback (TEH_plugin->cls); ret = TALER_MHD_reply_with_error (connection, MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_COMMIT_FAILED, + TALER_EC_GENERIC_DB_SOFT_FAILURE, NULL); goto cleanup; } - TEH_plugin->rollback (TEH_plugin->cls); - } - if (GNUNET_DB_STATUS_SOFT_ERROR == qs) - { - GNUNET_break (0); - TEH_plugin->rollback (TEH_plugin->cls); - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SOFT_FAILURE, - NULL); - goto cleanup; } /* Generate final (positive) response */ ret = reply_refreshes_reveal_success (connection, diff --git a/src/exchange/taler-exchange-httpd_reserves_close.c b/src/exchange/taler-exchange-httpd_reserves_close.c index 98873529a..711129927 100644 --- a/src/exchange/taler-exchange-httpd_reserves_close.c +++ b/src/exchange/taler-exchange-httpd_reserves_close.c @@ -30,7 +30,6 @@ #include "taler-exchange-httpd_common_kyc.h" #include "taler-exchange-httpd_keys.h" #include "taler-exchange-httpd_reserves_close.h" -#include "taler-exchange-httpd_withdraw.h" #include "taler-exchange-httpd_responses.h" @@ -343,7 +342,7 @@ reserve_close_transaction ( TALER_KYCLOGIC_KYC_TRIGGER_RESERVE_CLOSE, rcc->payto_uri, &rcc->kyc_payto, - NULL, /* no account_pub */ + NULL, /* no account_pub: this is about the origin/destination account */ &amount_it, rcc, &reserve_close_legi_cb, @@ -548,7 +547,8 @@ TEH_handler_reserves_close ( return TEH_RESPONSE_reply_kyc_required ( rc->connection, &rcc->kyc_payto, - &rcc->kyc); + &rcc->kyc, + false); } if (GNUNET_OK != diff --git a/src/exchange/taler-exchange-httpd_reserves_history.c b/src/exchange/taler-exchange-httpd_reserves_history.c index 61e6043a2..24f836cdd 100644 --- a/src/exchange/taler-exchange-httpd_reserves_history.c +++ b/src/exchange/taler-exchange-httpd_reserves_history.c @@ -466,9 +466,8 @@ TEH_handler_reserves_history ( if (NULL == rh) { /* 204: empty history */ - resp = MHD_create_response_from_buffer (0, - "", - MHD_RESPMEM_PERSISTENT); + resp = MHD_create_response_from_buffer_static (0, + ""); http_status = MHD_HTTP_NO_CONTENT; } else diff --git a/src/exchange/taler-exchange-httpd_reserves_purse.c b/src/exchange/taler-exchange-httpd_reserves_purse.c index 5774e10ea..26425448b 100644 --- a/src/exchange/taler-exchange-httpd_reserves_purse.c +++ b/src/exchange/taler-exchange-httpd_reserves_purse.c @@ -32,7 +32,6 @@ #include "taler-exchange-httpd_common_kyc.h" #include "taler-exchange-httpd_reserves_purse.h" #include "taler-exchange-httpd_responses.h" -#include "taler-exchange-httpd_withdraw.h" #include "taler_exchangedb_lib.h" #include "taler-exchange-httpd_keys.h" @@ -220,7 +219,7 @@ amount_iterator (void *cls, enum GNUNET_GenericReturnValue ret; ret = cb (cb_cls, - &rpc->deposit_total, + &rpc->pd.target_amount, GNUNET_TIME_absolute_get ()); GNUNET_break (GNUNET_SYSERR != ret); if (GNUNET_OK != ret) @@ -850,9 +849,11 @@ TEH_handler_reserves_purse ( TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, "requirement row not set"); } - return TEH_RESPONSE_reply_kyc_required (connection, - &rpc->h_payto, - &rpc->kyc); + return TEH_RESPONSE_reply_kyc_required ( + connection, + &rpc->h_payto, + &rpc->kyc, + false); } { diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c index 589cef2b1..0405c28fd 100644 --- a/src/exchange/taler-exchange-httpd_responses.c +++ b/src/exchange/taler-exchange-httpd_responses.c @@ -338,9 +338,11 @@ TEH_RESPONSE_reply_purse_created ( MHD_RESULT -TEH_RESPONSE_reply_kyc_required (struct MHD_Connection *connection, - const struct TALER_PaytoHashP *h_payto, - const struct TALER_EXCHANGEDB_KycStatus *kyc) +TEH_RESPONSE_reply_kyc_required ( + struct MHD_Connection *connection, + const struct TALER_PaytoHashP *h_payto, + const struct TALER_EXCHANGEDB_KycStatus *kyc, + bool bad_kyc_auth) { return TALER_MHD_REPLY_JSON_PACK ( connection, @@ -348,6 +350,18 @@ TEH_RESPONSE_reply_kyc_required (struct MHD_Connection *connection, TALER_JSON_pack_ec (TALER_EC_EXCHANGE_GENERIC_KYC_REQUIRED), GNUNET_JSON_pack_data_auto ("h_payto", h_payto), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_data_auto ( + "account_pub", + (kyc->have_account_pub + ? &kyc->account_pub + : NULL))), + GNUNET_JSON_pack_allow_null ( + bad_kyc_auth + ? GNUNET_JSON_pack_bool ("bad_kyc_auth", + bad_kyc_auth) + : GNUNET_JSON_pack_string ("bad_kyc_auth", + NULL)), GNUNET_JSON_pack_uint64 ("requirement_row", kyc->requirement_row)); } diff --git a/src/exchange/taler-exchange-httpd_responses.h b/src/exchange/taler-exchange-httpd_responses.h index 77ca9d557..79f505538 100644 --- a/src/exchange/taler-exchange-httpd_responses.h +++ b/src/exchange/taler-exchange-httpd_responses.h @@ -89,12 +89,18 @@ TEH_RESPONSE_reply_reserve_age_restriction_required ( * @param connection connection to the client * @param h_payto account identifier to include in reply * @param kyc details about the KYC requirements + * @param bad_kyc_auth true if the target_pub of the + * @a h_payto account does not match the merchant_pub + * from the operation and thus a KYC AUTH transfer is + * required * @return MHD result code */ MHD_RESULT -TEH_RESPONSE_reply_kyc_required (struct MHD_Connection *connection, - const struct TALER_PaytoHashP *h_payto, - const struct TALER_EXCHANGEDB_KycStatus *kyc); +TEH_RESPONSE_reply_kyc_required ( + struct MHD_Connection *connection, + const struct TALER_PaytoHashP *h_payto, + const struct TALER_EXCHANGEDB_KycStatus *kyc, + bool bad_kyc_auth); /** diff --git a/src/exchange/taler-exchange-httpd_spa.c b/src/exchange/taler-exchange-httpd_spa.c index a161125c6..6a4defb22 100644 --- a/src/exchange/taler-exchange-httpd_spa.c +++ b/src/exchange/taler-exchange-httpd_spa.c @@ -24,6 +24,7 @@ #include "taler_mhd_lib.h" #include <gnunet/gnunet_mhd_compat.h> #include "taler-exchange-httpd.h" +#include "taler-exchange-httpd_spa.h" /** @@ -42,18 +43,7 @@ TEH_handler_aml_spa (struct TEH_RequestContext *rc, const char *const args[]) { const char *path = args[0]; - struct TALER_AccountAccessTokenP tok; - if (GNUNET_OK == - GNUNET_STRINGS_string_to_data (path, - strlen (path), - &tok, - sizeof (tok))) - { - /* The access token is used internally by the SPA, - we simply map all access tokens to "index.html" */ - path = "index.html"; - } return TALER_MHD_spa_handler (aml_spa, rc->connection, path); @@ -65,7 +55,27 @@ TEH_handler_kyc_spa (struct TEH_RequestContext *rc, const char *const args[]) { const char *path = args[0]; + struct TALER_AccountAccessTokenP tok; + if (NULL == path) + { + GNUNET_break_op (0); + return TALER_MHD_reply_with_error ( + rc->connection, + MHD_HTTP_FORBIDDEN, + TALER_EC_GENERIC_TOKEN_PERMISSION_INSUFFICIENT, + "no account access token specified"); + } + if (GNUNET_OK == + GNUNET_STRINGS_string_to_data (path, + strlen (path), + &tok, + sizeof (tok))) + { + /* The access token is used internally by the SPA, + we simply map all access tokens to "index.html" */ + path = "index.html"; + } return TALER_MHD_spa_handler (kyc_spa, rc->connection, path); @@ -93,11 +103,15 @@ TEH_spa_init () } +/* Suppresses warning */ +void __attribute__ ((destructor)) +get_spa_fini (void); + /** * Nicely shut down. */ void __attribute__ ((destructor)) -get_spa_fini () +get_spa_fini (void) { if (NULL != kyc_spa) { diff --git a/src/exchange/taler-exchange-httpd_terms.c b/src/exchange/taler-exchange-httpd_terms.c index 10114f157..04966dda8 100644 --- a/src/exchange/taler-exchange-httpd_terms.c +++ b/src/exchange/taler-exchange-httpd_terms.c @@ -25,6 +25,7 @@ #include <microhttpd.h> #include "taler_mhd_lib.h" #include "taler-exchange-httpd_responses.h" +#include "taler-exchange-httpd_terms.h" /** * Our terms of service. diff --git a/src/exchange/taler-exchange-httpd_withdraw.c b/src/exchange/taler-exchange-httpd_withdraw.c deleted file mode 100644 index 320d02171..000000000 --- a/src/exchange/taler-exchange-httpd_withdraw.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2024 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation; either version 3, - or (at your option) any later version. - - TALER is distributed in the hope that 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 TALER; see the file COPYING. If not, - see <http://www.gnu.org/licenses/> -*/ -/** - * @file taler-exchange-httpd_withdraw.c - * @brief Common logic for withdraw operations - * @author Florian Dold - * @author Benedikt Mueller - * @author Christian Grothoff - */ -#include "platform.h" -#include <gnunet/gnunet_util_lib.h> -#include <jansson.h> -#include "taler-exchange-httpd.h" -#include "taler_json_lib.h" -#include "taler_kyclogic_lib.h" -#include "taler_mhd_lib.h" -#include "taler-exchange-httpd_common_kyc.h" -#include "taler-exchange-httpd_withdraw.h" -#include "taler-exchange-httpd_responses.h" -#include "taler_util.h" - - -/** - * Closure for #withdraw_amount_cb(). - */ -struct WithdrawContext -{ - /** - * Total amount being withdrawn now. - */ - const struct TALER_Amount *withdraw_total; - - /** - * Current time. - */ - struct GNUNET_TIME_Timestamp now; - - /** - * Account we are checking against. - */ - struct TALER_PaytoHashP h_payto; -}; - - -/** - * Function called to iterate over KYC-relevant transaction amounts for a - * particular time range. Called within a database transaction, so must - * not start a new one. - * - * @param cls closure, identifies the event type and account to iterate - * over events for - * @param limit maximum time-range for which events should be fetched - * (timestamp in the past) - * @param cb function to call on each event found, events must be returned - * in reverse chronological order - * @param cb_cls closure for @a cb, of type struct AgeWithdrawContext - * @return transaction status - */ -static enum GNUNET_DB_QueryStatus -withdraw_amount_cb ( - void *cls, - struct GNUNET_TIME_Absolute limit, - TALER_EXCHANGEDB_KycAmountCallback cb, - void *cb_cls) -{ - struct WithdrawContext *wc = cls; - enum GNUNET_GenericReturnValue ret; - enum GNUNET_DB_QueryStatus qs; - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Signaling amount %s for KYC check during age-withdrawal\n", - TALER_amount2s (wc->withdraw_total)); - ret = cb (cb_cls, - wc->withdraw_total, - wc->now.abs_time); - GNUNET_break (GNUNET_SYSERR != ret); - if (GNUNET_OK != ret) - return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; - qs = TEH_plugin->select_withdraw_amounts_for_kyc_check ( - TEH_plugin->cls, - &wc->h_payto, - limit, - cb, - cb_cls); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Got %d additional transactions for this age-withdrawal and limit %llu\n", - qs, - (unsigned long long) limit.abs_value_us); - GNUNET_break (qs >= 0); - return qs; -} - - -enum GNUNET_DB_QueryStatus -TEH_withdraw_kyc_check ( - struct TALER_EXCHANGEDB_KycStatus *kyc, - struct TALER_PaytoHashP *h_payto, - struct MHD_Connection *connection, - MHD_RESULT *mhd_ret, - const struct TALER_ReservePublicKeyP *reserve_pub, - const struct TALER_Amount *withdraw_total, - struct GNUNET_TIME_Timestamp now - ) -{ - enum GNUNET_DB_QueryStatus qs; - struct WithdrawContext wc = { - .withdraw_total = withdraw_total, - .now = now - }; - char *payto_uri; - - /* Check if the money came from a wire transfer */ - qs = TEH_plugin->reserves_get_origin ( - TEH_plugin->cls, - reserve_pub, - &wc.h_payto, - &payto_uri); - if (qs < 0) - { - if (GNUNET_DB_STATUS_HARD_ERROR == qs) - *mhd_ret = TALER_MHD_reply_with_error ( - connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_FETCH_FAILED, - "reserves_get_origin"); - return qs; - } - /* If _no_ results, reserve was created by merge, - in which case no KYC check is required as the - merge already did that. */ - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) - return qs; - *h_payto = wc.h_payto; - qs = TEH_legitimization_check ( - kyc, - connection, - mhd_ret, - TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW, - payto_uri, - &wc.h_payto, - NULL, - &withdraw_amount_cb, - &wc); - GNUNET_free (payto_uri); - return qs; -} diff --git a/src/exchange/taler-exchange-httpd_withdraw.h b/src/exchange/taler-exchange-httpd_withdraw.h deleted file mode 100644 index 45ac6340f..000000000 --- a/src/exchange/taler-exchange-httpd_withdraw.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2022 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Affero General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - TALER is distributed in the hope that 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 - TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file taler-exchange-httpd_withdraw.h - * @brief common code for withdraw requests - * @author Christian Grothoff - */ -#ifndef TALER_EXCHANGE_HTTPD_WITHDRAW_H -#define TALER_EXCHANGE_HTTPD_WITHDRAW_H - -#include <microhttpd.h> -#include "taler-exchange-httpd.h" - - -/** - * Do legitimization check for withdrawing @a withdraw_total - * from @a reserve_pub at time @a now. - * - * @param[out] kyc set to kyc status - * @param[out] h_payto set to payto hash of origin account - * @param[in,out] connection used to return hard errors - * @param[out] mhd_ret set if errors were returned - * (only on hard error) - * @param reserve_pub reserve from which we withdraw - * @param withdraw_total how much are being withdrawn - * @param now current time - * @return transaction status, error will have been - * queued if transaction status is set to hard error - */ -enum GNUNET_DB_QueryStatus -TEH_withdraw_kyc_check ( - struct TALER_EXCHANGEDB_KycStatus *kyc, - struct TALER_PaytoHashP *h_payto, - struct MHD_Connection *connection, - MHD_RESULT *mhd_ret, - const struct TALER_ReservePublicKeyP *reserve_pub, - const struct TALER_Amount *withdraw_total, - struct GNUNET_TIME_Timestamp now); - -#endif diff --git a/src/exchange/taler-exchange-router.c b/src/exchange/taler-exchange-router.c index a1a247194..c20795edf 100644 --- a/src/exchange/taler-exchange-router.c +++ b/src/exchange/taler-exchange-router.c @@ -426,10 +426,6 @@ main (int argc, }; enum GNUNET_GenericReturnValue ret; - if (GNUNET_OK != - GNUNET_STRINGS_get_utf8_args (argc, argv, - &argc, &argv)) - return EXIT_INVALIDARGUMENT; TALER_OS_init (); ret = GNUNET_PROGRAM_run ( argc, argv, @@ -438,7 +434,6 @@ main (int argc, "background process that routes P2P transfers"), options, &run, NULL); - GNUNET_free_nz ((void *) argv); if (GNUNET_SYSERR == ret) return EXIT_INVALIDARGUMENT; if (GNUNET_NO == ret) diff --git a/src/exchange/taler-exchange-transfer.c b/src/exchange/taler-exchange-transfer.c index 9724b41fc..399220e49 100644 --- a/src/exchange/taler-exchange-transfer.c +++ b/src/exchange/taler-exchange-transfer.c @@ -895,10 +895,6 @@ main (int argc, }; enum GNUNET_GenericReturnValue ret; - if (GNUNET_OK != - GNUNET_STRINGS_get_utf8_args (argc, argv, - &argc, &argv)) - return EXIT_INVALIDARGUMENT; TALER_OS_init (); ret = GNUNET_PROGRAM_run ( argc, argv, @@ -907,7 +903,6 @@ main (int argc, "background process that executes outgoing wire transfers"), options, &run, NULL); - GNUNET_free_nz ((void *) argv); if (GNUNET_SYSERR == ret) return EXIT_INVALIDARGUMENT; if (GNUNET_NO == ret) diff --git a/src/exchange/taler-exchange-wirewatch.c b/src/exchange/taler-exchange-wirewatch.c index 174eb8aff..a7d97cc63 100644 --- a/src/exchange/taler-exchange-wirewatch.c +++ b/src/exchange/taler-exchange-wirewatch.c @@ -482,10 +482,6 @@ transaction_completed (void) GNUNET_SCHEDULER_shutdown (); return; } - fprintf (stderr, - "XXX: %d %d\n", - hh_returned_data, - hh_account_404); if (! (hh_returned_data || hh_account_404) ) { /* Enforce long-polling delay even if the server ignored it @@ -581,6 +577,10 @@ process_reply (const struct TALER_BANK_CreditDetails *details, struct TALER_EXCHANGEDB_ReserveInInfo reserves[details_length]; unsigned int j = 0; + /* make compiler happy */ + memset (qss, + 0, + sizeof (qss)); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Importing %u transactions\n", details_length); @@ -1097,10 +1097,6 @@ main (int argc, enum GNUNET_GenericReturnValue ret; longpoll_timeout = LONGPOLL_TIMEOUT; - if (GNUNET_OK != - GNUNET_STRINGS_get_utf8_args (argc, argv, - &argc, &argv)) - return EXIT_INVALIDARGUMENT; TALER_OS_init (); ret = GNUNET_PROGRAM_run ( argc, argv, @@ -1109,7 +1105,6 @@ main (int argc, "background process that watches for incoming wire transfers from customers"), options, &run, NULL); - GNUNET_free_nz ((void *) argv); if (GNUNET_SYSERR == ret) return EXIT_INVALIDARGUMENT; if (GNUNET_NO == ret) diff --git a/src/exchange/test_taler_exchange_httpd.conf b/src/exchange/test_taler_exchange_httpd.conf index 7e7ff8b45..f5fc5f059 100644 --- a/src/exchange/test_taler_exchange_httpd.conf +++ b/src/exchange/test_taler_exchange_httpd.conf @@ -68,7 +68,7 @@ ENABLE_CREDIT = YES [exchange-accountcredentials-1] WIRE_GATEWAY_AUTH_METHOD = basic USERNAME = Exchange -PASSWORD = x +PASSWORD = password WIRE_GATEWAY_URL = "http://localhost:8082/accounts/3/taler-wire-gateway/" # Coins for the tests. diff --git a/src/exchangedb/.gitignore b/src/exchangedb/.gitignore index e4c628e66..42614b8e6 100644 --- a/src/exchangedb/.gitignore +++ b/src/exchangedb/.gitignore @@ -15,3 +15,4 @@ test-exchangedb-populate-ready-deposit-postgres test-exchangedb-populate-select-refunds-by-coin-postgres exchange-0004.sql exchange-0005.sql +exchange-0006.sql diff --git a/src/exchangedb/0005-kyc_attributes.sql b/src/exchangedb/0005-kyc_attributes.sql index 1cffd4cb6..f8f40f66b 100644 --- a/src/exchangedb/0005-kyc_attributes.sql +++ b/src/exchangedb/0005-kyc_attributes.sql @@ -28,6 +28,7 @@ BEGIN ' DROP COLUMN kyc_prox' ',DROP COLUMN provider' ',DROP COLUMN satisfied_checks' + ',DROP CONSTRAINT kyc_attributes_pkey' ',ADD COLUMN trigger_outcome_serial INT8 NOT NULL' ';' ,table_name @@ -43,6 +44,26 @@ BEGIN END $$; + +CREATE OR REPLACE FUNCTION constrain_table_kyc_attributes5( + IN partition_suffix TEXT +) +RETURNS void +LANGUAGE plpgsql +AS $$ +DECLARE + table_name TEXT DEFAULT 'kyc_attributes'; +BEGIN + table_name = concat_ws('_', table_name, partition_suffix); + -- To search accounts + EXECUTE FORMAT ( + 'CREATE INDEX ' || table_name || '_h_payto_index ' + 'ON ' || table_name || ' ' + '(h_payto);' + ); +END $$; + + CREATE FUNCTION foreign_table_kyc_attributes5() RETURNS void LANGUAGE plpgsql @@ -73,6 +94,11 @@ INSERT INTO exchange_tables ,FALSE), ('kyc_attributes5' ,'exchange-0005' + ,'constrain' + ,TRUE + ,FALSE), + ('kyc_attributes5' + ,'exchange-0005' ,'foreign' ,TRUE ,FALSE); diff --git a/src/exchangedb/0005-legitimization_measures.sql b/src/exchangedb/0005-legitimization_measures.sql index ce4b4e23c..189e71e1f 100644 --- a/src/exchangedb/0005-legitimization_measures.sql +++ b/src/exchangedb/0005-legitimization_measures.sql @@ -27,7 +27,7 @@ BEGIN ',access_token BYTEA NOT NULL CHECK (LENGTH(access_token)=32)' ',start_time INT8 NOT NULL' ',jmeasures TEXT NOT NULL' - ',display_priority INT4 NOT NULL' + ',display_priority INT4 NOT NULL' -- DEAD? ',is_finished BOOL NOT NULL DEFAULT(FALSE)' ') %s ;' ,'legitimization_measures' @@ -64,7 +64,7 @@ BEGIN ,partition_suffix ); PERFORM comment_partitioned_column( - 'Display priority of the rule that triggered this measure; if in the meantime another rule also triggers, the measure is only replaced if the new rule has a higher display priority' + 'Display priority of the rule that triggered this measure; if in the meantime another rule also triggers, the measure is only replaced if the new rule has a higher display priority; probably not really useful, as right now there is only ever one set of legitimization_measures active at any time, might be removed in the future' ,'display_priority' ,'legitimization_measures' ,partition_suffix diff --git a/src/exchangedb/0005-legitimization_outcomes.sql b/src/exchangedb/0005-legitimization_outcomes.sql index 1c7405c99..d132b682f 100644 --- a/src/exchangedb/0005-legitimization_outcomes.sql +++ b/src/exchangedb/0005-legitimization_outcomes.sql @@ -61,7 +61,7 @@ BEGIN ,partition_suffix ); PERFORM comment_partitioned_column( - 'name of the measure to trigger immediately, NULL for none' + 'space-separated list of names of measures to trigger immediately, NULL for none, prefixed with a "+" to indicate AND combination for the measures' ,'new_measure_name' ,'legitimization_outcomes' ,partition_suffix diff --git a/src/exchangedb/0005-legitimization_processes.sql b/src/exchangedb/0005-legitimization_processes.sql index db81b799d..c1bffca7d 100644 --- a/src/exchangedb/0005-legitimization_processes.sql +++ b/src/exchangedb/0005-legitimization_processes.sql @@ -81,6 +81,11 @@ BEGIN ' ADD CONSTRAINT ' || table_name || '_foreign_key_legitimization_measure' ' FOREIGN KEY (legitimization_measure_serial_id)' ' REFERENCES legitimization_measures (legitimization_measure_serial_id)'); + + EXECUTE FORMAT ( + 'ALTER TABLE ' || table_name || + ' ADD CONSTRAINT ' || table_name || '_unique_measure_and_index' + ' UNIQUE (legitimization_measure_serial_id,measure_index)'); END $$; diff --git a/src/exchangedb/0006-dummy.sql b/src/exchangedb/0006-dummy.sql new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/exchangedb/0006-dummy.sql diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am index 1407c2f8b..5472f41f5 100644 --- a/src/exchangedb/Makefile.am +++ b/src/exchangedb/Makefile.am @@ -21,10 +21,12 @@ sqlinputs = \ 0003-*.sql \ 0004-*.sql \ 0005-*.sql \ + 0006-*.sql \ exchange-0002.sql.in \ exchange-0003.sql.in \ exchange-0004.sql.in \ - exchange-0005.sql.in + exchange-0005.sql.in \ + exchange-0006.sql.in sql_DATA = \ benchmark-0001.sql \ @@ -35,6 +37,7 @@ sql_DATA = \ exchange-0003.sql \ exchange-0004.sql \ exchange-0005.sql \ + exchange-0006.sql \ drop.sql \ procedures.sql @@ -49,6 +52,7 @@ CLEANFILES = \ exchange-0003.sql \ exchange-0004.sql \ exchange-0005.sql \ + exchange-0006.sql \ procedures.sql procedures.sql: procedures.sql.in exchange_do_*.sql @@ -76,6 +80,11 @@ exchange-0005.sql: exchange-0005.sql.in 0005-*.sql gcc -E -P -undef - < exchange-0005.sql.in 2>/dev/null | sed -e "s/--.*//" | awk 'NF' - >$@ chmod ugo-w $@ +exchange-0006.sql: exchange-0006.sql.in 0006-*.sql + chmod +w $@ 2> /dev/null || true + gcc -E -P -undef - < exchange-0006.sql.in 2>/dev/null | sed -e "s/--.*//" | awk 'NF' - >$@ + chmod ugo-w $@ + check_SCRIPTS = \ test_idempotency.sh @@ -101,25 +110,27 @@ libtaler_plugin_exchangedb_postgres_la_SOURCES = \ plugin_exchangedb_common.c plugin_exchangedb_common.h \ pg_setup_wire_target.h pg_setup_wire_target.c \ pg_compute_shard.h pg_compute_shard.c \ - plugin_exchangedb_postgres.c pg_helper.h \ + plugin_exchangedb_postgres.c plugin_exchangedb_postgres.h \ + pg_helper.h \ pg_reserves_update.h pg_reserves_update.c \ pg_select_aggregation_amounts_for_kyc_check.h pg_select_aggregation_amounts_for_kyc_check.c \ pg_lookup_wire_fee_by_time.h pg_lookup_wire_fee_by_time.c \ pg_get_kyc_rules.h pg_get_kyc_rules.c \ pg_get_pending_kyc_requirement_process.h pg_get_pending_kyc_requirement_process.c \ pg_kyc_provider_account_lookup.h pg_kyc_provider_account_lookup.c \ - pg_insert_kyc_requirement_for_account.h pg_insert_kyc_requirement_for_account.c \ pg_lookup_kyc_process_by_account.h pg_lookup_kyc_process_by_account.c \ pg_update_kyc_process_by_row.h pg_update_kyc_process_by_row.c \ pg_insert_kyc_requirement_process.h pg_insert_kyc_requirement_process.c \ pg_select_withdraw_amounts_for_kyc_check.h pg_select_withdraw_amounts_for_kyc_check.c \ pg_select_merge_amounts_for_kyc_check.h pg_select_merge_amounts_for_kyc_check.c \ pg_profit_drains_set_finished.h pg_profit_drains_set_finished.c \ + pg_select_deposit_amounts_for_kyc_check.h pg_select_deposit_amounts_for_kyc_check.c \ pg_lookup_aml_history.h pg_lookup_aml_history.c \ pg_lookup_kyc_history.h pg_lookup_kyc_history.c \ pg_profit_drains_get_pending.h pg_profit_drains_get_pending.c \ pg_get_drain_profit.h pg_get_drain_profit.c \ pg_get_purse_deposit.h pg_get_purse_deposit.c \ + pg_do_check_deposit_idempotent.h pg_do_check_deposit_idempotent.c \ pg_insert_contract.h pg_insert_contract.c \ pg_select_contract.h pg_select_contract.c \ pg_select_purse_merge.h pg_select_purse_merge.c \ @@ -138,6 +149,7 @@ libtaler_plugin_exchangedb_postgres_la_SOURCES = \ pg_iterate_active_auditors.h pg_iterate_active_auditors.c \ pg_iterate_auditor_denominations.h pg_iterate_auditor_denominations.c \ pg_reserves_get.h pg_reserves_get.c \ + pg_lookup_rules_by_access_token.h pg_lookup_rules_by_access_token.c \ pg_reserves_get_origin.h pg_reserves_get_origin.c \ pg_drain_kyc_alert.h pg_drain_kyc_alert.c \ pg_reserves_in_insert.h pg_reserves_in_insert.c \ @@ -174,6 +186,7 @@ libtaler_plugin_exchangedb_postgres_la_SOURCES = \ pg_test_aml_officer.h pg_test_aml_officer.c \ pg_lookup_aml_officer.h pg_lookup_aml_officer.c \ pg_lookup_pending_legitimization.h pg_lookup_pending_legitimization.c \ + pg_lookup_completed_legitimization.h pg_lookup_completed_legitimization.c \ pg_lookup_active_legitimization.h pg_lookup_active_legitimization.c \ pg_trigger_aml_process.h pg_trigger_aml_process.c \ pg_insert_aml_decision.h pg_insert_aml_decision.c \ @@ -199,6 +212,7 @@ libtaler_plugin_exchangedb_postgres_la_SOURCES = \ pg_wire_prepare_data_mark_failed.h pg_wire_prepare_data_mark_failed.c \ pg_wire_prepare_data_get.h pg_wire_prepare_data_get.c \ pg_start_deferred_wire_out.h pg_start_deferred_wire_out.c \ + pg_insert_active_legitimization_measure.h pg_insert_active_legitimization_measure.c \ pg_store_wire_transfer_out.h pg_store_wire_transfer_out.c \ pg_gc.h pg_gc.c \ pg_lookup_kyc_status_by_token.h pg_lookup_kyc_status_by_token.c \ diff --git a/src/exchangedb/exchange-0006.sql.in b/src/exchangedb/exchange-0006.sql.in new file mode 100644 index 000000000..86d14b6d0 --- /dev/null +++ b/src/exchangedb/exchange-0006.sql.in @@ -0,0 +1,32 @@ +-- +-- This file is part of TALER +-- Copyright (C) 2014--2023 Taler Systems SA +-- +-- TALER is free software; you can redistribute it and/or modify it under the +-- terms of the GNU General Public License as published by the Free Software +-- Foundation; either version 3, or (at your option) any later version. +-- +-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY +-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +-- A PARTICULAR PURPOSE. See the GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License along with +-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> +-- + +BEGIN; + +SELECT _v.register_patch('exchange-0006', NULL, NULL); +SET search_path TO exchange; + +CREATE TYPE exchange_do_select_aggregations_above_serial_return_type + AS + ( + batch_deposit_serial_id INT8, + aggregation_serial_id INT8, + total_amount taler_amount + ); +COMMENT ON TYPE exchange_do_select_aggregations_above_serial_return_type + IS 'Return type for exchange_do_select_aggregations_above_serial'; + +COMMIT; diff --git a/src/exchangedb/exchange_do_check_deposit_idempotent.sql b/src/exchangedb/exchange_do_check_deposit_idempotent.sql new file mode 100644 index 000000000..1e7414dc0 --- /dev/null +++ b/src/exchangedb/exchange_do_check_deposit_idempotent.sql @@ -0,0 +1,123 @@ +-- +-- 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/> +-- +CREATE OR REPLACE FUNCTION exchange_do_check_deposit_idempotent( + -- For batch_deposits + IN in_shard INT8, + IN in_merchant_pub BYTEA, + IN in_wallet_timestamp INT8, + IN in_exchange_timestamp INT8, + IN in_refund_deadline INT8, + IN in_wire_deadline INT8, + IN in_h_contract_terms BYTEA, + IN in_wallet_data_hash BYTEA, -- can be NULL + IN in_wire_salt BYTEA, + IN in_wire_target_h_payto BYTEA, + IN in_policy_details_serial_id INT8, -- can be NULL + IN in_policy_blocked BOOLEAN, + -- For wire_targets + IN in_receiver_wire_account TEXT, + -- For coin_deposits + IN ina_coin_pub BYTEA[], + IN ina_coin_sig BYTEA[], + IN ina_amount_with_fee taler_amount[], + OUT out_exchange_timestamp INT8, + OUT out_is_idempotent BOOL + ) +LANGUAGE plpgsql +AS $$ +DECLARE + wtsi INT8; -- wire target serial id + bdsi INT8; -- batch_deposits serial id + i INT4; + ini_amount_with_fee taler_amount; + ini_coin_pub BYTEA; + ini_coin_sig BYTEA; +BEGIN +-- Shards: +-- SELECT wire_targets (by h_payto); +-- INSERT batch_deposits (by shard, merchant_pub), ON CONFLICT idempotency check; +-- PERFORM[] coin_deposits (by coin_pub), ON CONFLICT idempotency check; + +out_exchange_timestamp = in_exchange_timestamp; + +-- First, get the 'wtsi' +SELECT wire_target_serial_id + INTO wtsi + FROM wire_targets + WHERE wire_target_h_payto=in_wire_target_h_payto + AND payto_uri=in_receiver_wire_account; + +IF NOT FOUND +THEN + out_is_idempotent = FALSE; + RETURN; +END IF; + + +-- Idempotency check: see if an identical record exists. +-- We do select over merchant_pub, h_contract_terms and wire_target_h_payto +-- first to maximally increase the chance of using the existing index. +SELECT + exchange_timestamp + ,batch_deposit_serial_id + INTO + out_exchange_timestamp + ,bdsi + FROM batch_deposits + WHERE shard=in_shard + AND merchant_pub=in_merchant_pub + AND h_contract_terms=in_h_contract_terms + AND wire_target_h_payto=in_wire_target_h_payto + -- now check the rest, too + AND ( (wallet_data_hash=in_wallet_data_hash) OR + (wallet_data_hash IS NULL AND in_wallet_data_hash IS NULL) ) + AND wire_salt=in_wire_salt + AND wallet_timestamp=in_wallet_timestamp + AND refund_deadline=in_refund_deadline + AND wire_deadline=in_wire_deadline + AND ( (policy_details_serial_id=in_policy_details_serial_id) OR + (policy_details_serial_id IS NULL AND in_policy_details_serial_id IS NULL) ); + +IF NOT FOUND +THEN + out_is_idempotent=FALSE; + RETURN; +END IF; + + +-- Check each coin + +FOR i IN 1..array_length(ina_coin_pub,1) +LOOP + ini_coin_pub = ina_coin_pub[i]; + ini_coin_sig = ina_coin_sig[i]; + ini_amount_with_fee = ina_amount_with_fee[i]; + + PERFORM FROM coin_deposits + WHERE batch_deposit_serial_id=bdsi + AND coin_pub=ini_coin_pub + AND coin_sig=ini_coin_sig + AND amount_with_fee=ini_amount_with_fee; + IF NOT FOUND + THEN + out_is_idempotent=FALSE; + RETURN; + END IF; +END LOOP; -- end FOR all coins + +out_is_idempotent=TRUE; + +END $$; diff --git a/src/exchangedb/exchange_do_insert_active_legitimization_measure.sql b/src/exchangedb/exchange_do_insert_active_legitimization_measure.sql new file mode 100644 index 000000000..ce554dee7 --- /dev/null +++ b/src/exchangedb/exchange_do_insert_active_legitimization_measure.sql @@ -0,0 +1,51 @@ +-- +-- 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/> +-- + +DROP FUNCTION IF EXISTS exchange_do_insert_active_legitimization_measure; +CREATE FUNCTION exchange_do_insert_active_legitimization_measure( + IN in_access_token BYTEA, + IN in_start_time INT8, + IN in_jmeasures TEXT, + OUT out_legitimization_measure_serial_id INT8) +LANGUAGE plpgsql +AS $$ +BEGIN + +UPDATE legitimization_measures + SET is_finished=TRUE + WHERE access_token=in_access_token + AND NOT is_finished; + +INSERT INTO legitimization_measures + (access_token + ,start_time + ,jmeasures + ,display_priority) + VALUES + (in_access_token + ,in_start_time + ,in_jmeasures + ,1) + RETURNING + legitimization_measure_serial_id + INTO + out_legitimization_measure_serial_id; + +END $$; + + +COMMENT ON FUNCTION exchange_do_insert_active_legitimization_measure(BYTEA, INT8, TEXT) + IS 'Inserts legitimization measure for an account and marks all existing such measures as inactive'; diff --git a/src/exchangedb/exchange_do_insert_aml_decision.sql b/src/exchangedb/exchange_do_insert_aml_decision.sql index cf5ff530e..401d6e23e 100644 --- a/src/exchangedb/exchange_do_insert_aml_decision.sql +++ b/src/exchangedb/exchange_do_insert_aml_decision.sql @@ -15,15 +15,16 @@ -- DROP FUNCTION IF EXISTS exchange_do_insert_aml_decision; -CREATE OR REPLACE FUNCTION exchange_do_insert_aml_decision( +CREATE FUNCTION exchange_do_insert_aml_decision( + IN in_payto_uri TEXT, -- can be NULL! IN in_h_payto BYTEA, IN in_decision_time INT8, IN in_expiration_time INT8, - IN in_properties TEXT, + IN in_properties TEXT, -- can be NULL IN in_new_rules TEXT, IN in_to_investigate BOOLEAN, - IN in_new_measure_name TEXT, - IN in_jmeasures TEXT, + IN in_new_measure_name TEXT, -- can be NULL + IN in_jmeasures TEXT, -- can be NULL IN in_justification TEXT, IN in_decider_pub BYTEA, IN in_decider_sig BYTEA, @@ -36,7 +37,6 @@ AS $$ DECLARE my_outcome_serial_id INT8; my_access_token BYTEA; - my_max_dp INT4; BEGIN out_account_unknown=FALSE; @@ -79,43 +79,43 @@ ELSE out_last_date = 0; END IF; --- Note: in_payto_uri is allowed to be NULL *if* --- in_h_payto is already in wire_targets SELECT access_token INTO my_access_token FROM wire_targets WHERE wire_target_h_payto=in_h_payto; --- Very strange, should never happen that we --- take an AML decision on an unknown account! IF NOT FOUND THEN - out_account_unknown=TRUE; - RETURN; + IF in_payto_uri IS NULL + THEN + -- AML decision on an unknown account without payto_uri => fail. + out_account_unknown=TRUE; + RETURN; + END IF; + + INSERT INTO wire_targets + (wire_target_h_payto + ,payto_uri) + VALUES + (in_h_payto + ,in_payto_uri) + RETURNING access_token + INTO my_access_token; END IF; +-- AML decision: mark all active measures finished! +UPDATE legitimization_measures + SET is_finished=TRUE + WHERE access_token=my_access_token + AND NOT is_finished; + -- Did KYC measures get prescribed? -IF in_jmeasures IS NULL +IF in_jmeasures IS NOT NULL THEN - -- AML decision without measure: mark all - -- active measures finished! - UPDATE legitimization_measures - SET is_finished=TRUE - WHERE access_token=my_access_token - AND NOT is_finished; - -ELSE - -- Find current maximum DP - SELECT COALESCE(MAX(display_priority),0) - INTO my_max_dp - FROM legitimization_measures - WHERE access_token=my_access_token - AND NOT is_finished; - -- First check if a perfectly equivalent legi measure -- already exists, to avoid creating tons of duplicates. - UPDATE legitimization_measures - SET display_priority=GREATEST(my_max_dp,display_priority) + PERFORM + FROM legitimization_measures WHERE access_token=my_access_token AND jmeasures=in_jmeasures AND NOT is_finished; @@ -132,10 +132,10 @@ ELSE (my_access_token ,in_decision_time ,in_jmeasures - ,my_max_dp + 1); + ,1); END IF; - -- end if for where we had non-NULL in_jmeasures + -- end if for where we had in_jmeasures END IF; UPDATE legitimization_outcomes @@ -199,5 +199,5 @@ EXECUTE FORMAT ( END $$; -COMMENT ON FUNCTION exchange_do_insert_aml_decision(BYTEA, INT8, INT8, TEXT, TEXT, BOOLEAN, TEXT, TEXT, TEXT, BYTEA, BYTEA, TEXT) +COMMENT ON FUNCTION exchange_do_insert_aml_decision(TEXT, BYTEA, INT8, INT8, TEXT, TEXT, BOOLEAN, TEXT, TEXT, TEXT, BYTEA, BYTEA, TEXT) IS 'Checks whether the AML officer is eligible to make AML decisions and if so inserts the decision into the table'; diff --git a/src/exchangedb/exchange_do_insert_kyc_attributes.sql b/src/exchangedb/exchange_do_insert_kyc_attributes.sql index 0c907f279..e04775b83 100644 --- a/src/exchangedb/exchange_do_insert_kyc_attributes.sql +++ b/src/exchangedb/exchange_do_insert_kyc_attributes.sql @@ -115,17 +115,6 @@ UPDATE reserves ((current_balance).val > 0 ) ) AND (expiration_date > in_collection_time_ts); -IF in_to_investigate -THEN - INSERT INTO aml_status - (h_payto - ,status) - VALUES - (in_h_payto - ,1) - ON CONFLICT (h_payto) DO - UPDATE SET status=EXCLUDED.status | 1; -END IF; FOR i IN 1..COALESCE(array_length(ina_events,1),0) LOOP diff --git a/src/exchangedb/exchange_do_insert_programmatic_legitimization_outcome.sql b/src/exchangedb/exchange_do_insert_programmatic_legitimization_outcome.sql index 196632b44..ef0cb8fdb 100644 --- a/src/exchangedb/exchange_do_insert_programmatic_legitimization_outcome.sql +++ b/src/exchangedb/exchange_do_insert_programmatic_legitimization_outcome.sql @@ -154,18 +154,6 @@ INSERT INTO kyc_alerts (in_h_payto,1) ON CONFLICT DO NOTHING; -IF in_to_investigate -THEN - INSERT INTO aml_status - (h_payto - ,status) - VALUES - (in_h_payto - ,1) - ON CONFLICT (h_payto) DO - UPDATE SET status=EXCLUDED.status | 1; -END IF; - FOR i IN 1..COALESCE(array_length(ina_events,1),0) LOOP diff --git a/src/exchangedb/exchange_do_kycauth_in_insert.sql b/src/exchangedb/exchange_do_kycauth_in_insert.sql index 63d5cad3b..206c80f1a 100644 --- a/src/exchangedb/exchange_do_kycauth_in_insert.sql +++ b/src/exchangedb/exchange_do_kycauth_in_insert.sql @@ -15,14 +15,16 @@ -- -CREATE OR REPLACE PROCEDURE exchange_do_kycauth_in_insert( +DROP PROCEDURE IF EXISTS exchange_do_kycauth_in_insert; +CREATE PROCEDURE exchange_do_kycauth_in_insert( IN in_account_pub BYTEA, IN in_wire_reference INT8, IN in_credit taler_amount, IN in_wire_source_h_payto BYTEA, IN in_payto_uri TEXT, IN in_exchange_account_name TEXT, - IN in_execution_date INT8) + IN in_execution_date INT8, + IN in_notify_s TEXT) LANGUAGE plpgsql AS $$ BEGIN @@ -66,4 +68,8 @@ BEGIN ,in_account_pub); END IF; + EXECUTE FORMAT ( + 'NOTIFY %s' + ,in_notify_s); + END $$; diff --git a/src/exchangedb/exchange_do_lookup_kyc_requirement_by_row.sql b/src/exchangedb/exchange_do_lookup_kyc_requirement_by_row.sql index 9c7f8f081..e9a22aa84 100644 --- a/src/exchangedb/exchange_do_lookup_kyc_requirement_by_row.sql +++ b/src/exchangedb/exchange_do_lookup_kyc_requirement_by_row.sql @@ -15,8 +15,10 @@ -- -- @author: Christian Grothoff -CREATE OR REPLACE FUNCTION exchange_do_lookup_kyc_requirement_by_row( - IN in_legitimization_serial_id INT8, +DROP FUNCTION IF EXISTS exchange_do_lookup_kyc_requirement_by_row; + +CREATE FUNCTION exchange_do_lookup_kyc_requirement_by_row( + IN in_h_payto BYTEA, OUT out_account_pub BYTEA, -- NULL allowed OUT out_reserve_pub BYTEA, -- NULL allowed OUT out_access_token BYTEA, -- NULL if 'out_not_found' @@ -27,16 +29,16 @@ CREATE OR REPLACE FUNCTION exchange_do_lookup_kyc_requirement_by_row( LANGUAGE plpgsql AS $$ DECLARE - my_h_payto BYTEA; my_wtrec RECORD; my_lorec RECORD; BEGIN --- Find the access token. +-- Find the access token and the current account public key. SELECT access_token - INTO out_access_token - FROM legitimization_measures - WHERE legitimization_measure_serial_id=in_legitimization_serial_id; + ,target_pub + INTO my_wtrec + FROM wire_targets + WHERE wire_target_h_payto=in_h_payto; IF NOT FOUND THEN @@ -46,28 +48,17 @@ THEN END IF; out_not_found = FALSE; --- Find the payto hash and the current account public key. -SELECT target_pub - ,wire_target_h_payto - INTO my_wtrec - FROM wire_targets - WHERE access_token=out_access_token; - out_account_pub = my_wtrec.target_pub; -my_h_payto = my_wtrec.wire_target_h_payto; +out_access_token = my_wtrec.access_token; -- Check if there are active measures for the account. -SELECT NOT is_finished - INTO out_kyc_required +PERFORM FROM legitimization_measures WHERE access_token=out_access_token - ORDER BY start_time DESC + AND NOT is_finished LIMIT 1; -IF NOT FOUND -THEN - out_kyc_required=TRUE; -END IF; +out_kyc_required = FOUND; -- Get currently applicable rules. -- Only one should ever be active per account. @@ -75,7 +66,7 @@ SELECT jnew_rules ,to_investigate INTO my_lorec FROM legitimization_outcomes - WHERE h_payto=my_h_payto + WHERE h_payto=in_h_payto AND is_active; IF FOUND @@ -84,12 +75,12 @@ THEN out_aml_review=my_lorec.to_investigate; END IF; --- Get most recent reserve_in wire transfer, we also --- allow that one for authentication! +-- Check most recent reserve_in wire transfer, we also +-- allow that reserve public key for authentication! SELECT reserve_pub INTO out_reserve_pub FROM reserves_in - WHERE wire_source_h_payto=my_h_payto + WHERE wire_source_h_payto=in_h_payto ORDER BY execution_date DESC LIMIT 1; diff --git a/src/exchangedb/exchange_do_select_aggregations_above_serial.sql b/src/exchangedb/exchange_do_select_aggregations_above_serial.sql new file mode 100644 index 000000000..277cb7cc2 --- /dev/null +++ b/src/exchangedb/exchange_do_select_aggregations_above_serial.sql @@ -0,0 +1,72 @@ +-- +-- 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/> +-- +-- @author: Christian Grothoff + +CREATE OR REPLACE FUNCTION exchange_do_select_aggregations_above_serial( + IN in_min_serial_id INT8) +RETURNS SETOF exchange_do_select_aggregations_above_serial_return_type +LANGUAGE plpgsql +AS $$ +DECLARE + aggregation CURSOR + FOR + SELECT + batch_deposit_serial_id + ,aggregation_serial_id + FROM aggregation_tracking + WHERE aggregation_serial_id >= in_min_serial_id + ORDER BY aggregation_serial_id ASC; +DECLARE + my_total_val INT8; -- all deposits without wire +DECLARE + my_total_frac INT8; -- all deposits without wire (fraction, not normalized) +DECLARE + my_total taler_amount; -- amount that was originally deposited +DECLARE + my_batch_record RECORD; +DECLARE + i RECORD; +BEGIN + +OPEN aggregation; +LOOP + FETCH NEXT FROM aggregation INTO i; + EXIT WHEN NOT FOUND; + + SELECT + SUM((cdep.amount_with_fee).val) AS total_val + ,SUM((cdep.amount_with_fee).frac::INT8) AS total_frac + INTO + my_batch_record + FROM coin_deposits cdep + WHERE cdep.batch_deposit_serial_id = i.batch_deposit_serial_id; + + my_total_val=my_batch_record.total_val; + my_total_frac=my_batch_record.total_frac; + + -- Normalize total amount + my_total.val = my_total_val + my_total_frac / 100000000; + my_total.frac = my_total_frac % 100000000; + RETURN NEXT ( + i.batch_deposit_serial_id + ,i.aggregation_serial_id + ,my_total + ); + +END LOOP; +CLOSE aggregation; +RETURN; +END $$; diff --git a/src/exchangedb/exchange_do_trigger_kyc_rule_for_account.sql b/src/exchangedb/exchange_do_trigger_kyc_rule_for_account.sql index 21d8735db..9a224b7da 100644 --- a/src/exchangedb/exchange_do_trigger_kyc_rule_for_account.sql +++ b/src/exchangedb/exchange_do_trigger_kyc_rule_for_account.sql @@ -14,30 +14,48 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- -CREATE OR REPLACE FUNCTION exchange_do_trigger_kyc_rule_for_account( +DROP FUNCTION IF EXISTS exchange_do_trigger_kyc_rule_for_account; + +CREATE FUNCTION exchange_do_trigger_kyc_rule_for_account( IN in_h_payto BYTEA, - IN in_account_pub BYTEA, -- can be NULL + IN in_account_pub BYTEA, -- can be NULL, if given, should be SET + IN in_merchant_pub BYTEA, -- can be NULL IN in_payto_uri TEXT, -- can be NULL IN in_now INT8, IN in_jmeasures TEXT, IN in_display_priority INT4, - OUT out_legitimization_measure_serial_id INT8) + IN in_notify_s TEXT, + OUT out_legitimization_measure_serial_id INT8, + OUT out_bad_kyc_auth BOOL) LANGUAGE plpgsql AS $$ DECLARE + my_rec RECORD; my_access_token BYTEA; + my_account_pub BYTEA; + my_reserve_pub BYTEA; BEGIN -- Note: in_payto_uri is allowed to be NULL *if* -- in_h_payto is already in wire_targets + + SELECT - access_token + access_token + ,target_pub INTO - my_access_token + my_rec FROM wire_targets WHERE wire_target_h_payto=in_h_payto; -IF NOT FOUND +IF FOUND THEN + -- Extract details, determine if KYC auth matches. + my_access_token = my_rec.access_token; + my_account_pub = my_rec.target_pub; + out_bad_kyc_auth = COALESCE ((my_account_pub != in_merchant_pub), TRUE); +ELSE + -- No constraint on merchant_pub, just create + -- the wire_target. INSERT INTO wire_targets (payto_uri ,wire_target_h_payto @@ -49,8 +67,27 @@ THEN RETURNING access_token INTO my_access_token; + out_bad_kyc_auth=TRUE; END IF; +IF out_bad_kyc_auth +THEN + -- Check most recent reserve_in wire transfer, we also + -- allow that reserve public key for authentication! + SELECT reserve_pub + INTO my_reserve_pub + FROM reserves_in + WHERE wire_source_h_payto=in_h_payto + ORDER BY execution_date DESC + LIMIT 1; + IF FOUND + THEN + IF in_merchant_pub = my_reserve_pub + THEN + out_bad_kyc_auth = FALSE; + END IF; + END IF; +END IF; -- First check if a perfectly equivalent legi measure -- already exists, to avoid creating tons of duplicates. UPDATE legitimization_measures @@ -79,4 +116,9 @@ THEN out_legitimization_measure_serial_id; END IF; +EXECUTE FORMAT ( + 'NOTIFY %s' + ,in_notify_s); + + END $$; diff --git a/src/exchangedb/exchangedb_plugin.c b/src/exchangedb/exchangedb_plugin.c index 5dc41d988..68a916b4e 100644 --- a/src/exchangedb/exchangedb_plugin.c +++ b/src/exchangedb/exchangedb_plugin.c @@ -20,7 +20,7 @@ * @author Sree Harsha Totakura <sreeharsha@totakura.in> */ #include "platform.h" -#include "taler_exchangedb_plugin.h" +#include "taler_exchangedb_lib.h" #include <ltdl.h> diff --git a/src/exchangedb/perf_deposits_get_ready.c b/src/exchangedb/perf_deposits_get_ready.c index 005ea6843..1cb8c595a 100644 --- a/src/exchangedb/perf_deposits_get_ready.c +++ b/src/exchangedb/perf_deposits_get_ready.c @@ -68,8 +68,6 @@ static int result; */ static struct TALER_EXCHANGEDB_Plugin *plugin; -static struct TALER_DenomFeeSet fees; - static struct TALER_MerchantWireHashP h_wire_wt; /** @@ -203,6 +201,7 @@ run (void *cls) unsigned int *perm; unsigned long long duration_sq; struct TALER_EXCHANGEDB_RefreshRevealedCoin *ccoin; + struct TALER_DenomFeeSet fees; struct GNUNET_CRYPTO_BlindingInputValues bi = { .cipher = GNUNET_CRYPTO_BSA_RSA, .rc = 0 diff --git a/src/exchangedb/perf_get_link_data.c b/src/exchangedb/perf_get_link_data.c index 817789afc..f2c612e16 100644 --- a/src/exchangedb/perf_get_link_data.c +++ b/src/exchangedb/perf_get_link_data.c @@ -28,24 +28,25 @@ * Report line of error if @a cond is true, and jump to label "drop". */ #define FAILIF(cond) \ - do { \ - if (! (cond)) {break;} \ - GNUNET_break (0); \ - goto drop; \ - } while (0) + do { \ + if (! (cond)) {break;} \ + GNUNET_break (0); \ + goto drop; \ + } while (0) /** * Initializes @a ptr with random data. */ #define RND_BLK(ptr) \ - GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, ptr, sizeof (*ptr)) + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, ptr, sizeof (* \ + ptr)) /** * Initializes @a ptr with zeros. */ #define ZR_BLK(ptr) \ - memset (ptr, 0, sizeof (*ptr)) + memset (ptr, 0, sizeof (*ptr)) #define CURRENCY "EUR" #define RSA_KEY_SIZE 1024 @@ -58,7 +59,6 @@ * Database plugin under test. */ static struct TALER_EXCHANGEDB_Plugin *plugin; -static struct TALER_DenomFeeSet fees; /** * Denomination keys used for fresh coins in melt test. */ @@ -215,6 +215,7 @@ run (void *cls) struct TALER_ExchangeWithdrawValues alg_values = { .blinding_inputs = &bi }; + struct TALER_DenomFeeSet fees; ref = GNUNET_new_array (ROUNDS + 1, struct TALER_EXCHANGEDB_Refund); @@ -307,10 +308,10 @@ run (void *cls) struct TALER_EXCHANGEDB_RefreshRevealedCoin *revealed_coin = &revealed_coins[p]; struct TALER_BlindedPlanchet *bp = &revealed_coin->blinded_planchet; - bp->blinded_message = GNUNET_new (struct GNUNET_CRYPTO_BlindedMessage); - struct GNUNET_CRYPTO_RsaBlindedMessage *rp = - &bp->blinded_message->details.rsa_blinded_message; + struct GNUNET_CRYPTO_RsaBlindedMessage *rp; + bp->blinded_message = GNUNET_new (struct GNUNET_CRYPTO_BlindedMessage); + rp = &bp->blinded_message->details.rsa_blinded_message; /* h_coin_ev must be unique, but we only have MELT_NEW_COINS created above for NUM_ROWS iterations; instead of making "all new" coins, we simply randomize the hash here as nobody is checking for consistency diff --git a/src/exchangedb/perf_select_refunds_by_coin.c b/src/exchangedb/perf_select_refunds_by_coin.c index 84825d6d7..6b9592919 100644 --- a/src/exchangedb/perf_select_refunds_by_coin.c +++ b/src/exchangedb/perf_select_refunds_by_coin.c @@ -67,7 +67,6 @@ static int result; */ static struct TALER_EXCHANGEDB_Plugin *plugin; -static struct TALER_DenomFeeSet fees; static struct TALER_MerchantWireHashP h_wire_wt; @@ -231,6 +230,7 @@ run (void *cls) unsigned long long duration_sq; struct TALER_EXCHANGEDB_RefreshRevealedCoin *ccoin; struct TALER_DenominationPublicKey *new_denom_pubs = NULL; + struct TALER_DenomFeeSet fees; unsigned int count = 0; ref = GNUNET_new_array (ROUNDS + 1, diff --git a/src/exchangedb/pg_batch_ensure_coin_known.c b/src/exchangedb/pg_batch_ensure_coin_known.c index aca2732c6..fdf3852b2 100644 --- a/src/exchangedb/pg_batch_ensure_coin_known.c +++ b/src/exchangedb/pg_batch_ensure_coin_known.c @@ -38,16 +38,6 @@ insert1 (struct PostgresClosure *pg, enum GNUNET_DB_QueryStatus qs; bool is_denom_pub_hash_null = false; bool is_age_hash_null = false; - PREPARE (pg, - "batch1_known_coin", - "SELECT" - " existed1 AS existed" - ",known_coin_id1 AS known_coin_id" - ",denom_pub_hash1 AS denom_hash" - ",age_commitment_hash1 AS h_age_commitment" - " FROM exchange_do_batch1_known_coin" - " ($1, $2, $3, $4);" - ); struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (&coin[0].coin_pub), GNUNET_PQ_query_param_auto_from_type (&coin[0].denom_pub_hash), @@ -71,6 +61,16 @@ insert1 (struct PostgresClosure *pg, GNUNET_PQ_result_spec_end }; + PREPARE (pg, + "batch1_known_coin", + "SELECT" + " existed1 AS existed" + ",known_coin_id1 AS known_coin_id" + ",denom_pub_hash1 AS denom_hash" + ",age_commitment_hash1 AS h_age_commitment" + " FROM exchange_do_batch1_known_coin" + " ($1, $2, $3, $4);" + ); qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, "batch1_known_coin", params, @@ -140,21 +140,6 @@ insert2 (struct PostgresClosure *pg, enum GNUNET_DB_QueryStatus qs; bool is_denom_pub_hash_null[2] = {false, false}; bool is_age_hash_null[2] = {false, false}; - - PREPARE (pg, - "batch2_known_coin", - "SELECT" - " existed1 AS existed" - ",known_coin_id1 AS known_coin_id" - ",denom_pub_hash1 AS denom_hash" - ",age_commitment_hash1 AS h_age_commitment" - ",existed2 AS existed2" - ",known_coin_id2 AS known_coin_id2" - ",denom_pub_hash2 AS denom_hash2" - ",age_commitment_hash2 AS h_age_commitment2" - " FROM exchange_do_batch2_known_coin" - " ($1, $2, $3, $4, $5, $6, $7, $8);" - ); struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (&coin[0].coin_pub), GNUNET_PQ_query_param_auto_from_type (&coin[0].denom_pub_hash), @@ -195,6 +180,20 @@ insert2 (struct PostgresClosure *pg, GNUNET_PQ_result_spec_end }; + PREPARE (pg, + "batch2_known_coin", + "SELECT" + " existed1 AS existed" + ",known_coin_id1 AS known_coin_id" + ",denom_pub_hash1 AS denom_hash" + ",age_commitment_hash1 AS h_age_commitment" + ",existed2 AS existed2" + ",known_coin_id2 AS known_coin_id2" + ",denom_pub_hash2 AS denom_hash2" + ",age_commitment_hash2 AS h_age_commitment2" + " FROM exchange_do_batch2_known_coin" + " ($1, $2, $3, $4, $5, $6, $7, $8);" + ); qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, "batch2_known_coin", params, @@ -259,28 +258,6 @@ insert4 (struct PostgresClosure *pg, 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}; - PREPARE (pg, - "batch4_known_coin", - "SELECT" - " existed1 AS existed" - ",known_coin_id1 AS known_coin_id" - ",denom_pub_hash1 AS denom_hash" - ",age_commitment_hash1 AS h_age_commitment" - ",existed2 AS existed2" - ",known_coin_id2 AS known_coin_id2" - ",denom_pub_hash2 AS denom_hash2" - ",age_commitment_hash2 AS h_age_commitment2" - ",existed3 AS existed3" - ",known_coin_id3 AS known_coin_id3" - ",denom_pub_hash3 AS denom_hash3" - ",age_commitment_hash3 AS h_age_commitment3" - ",existed4 AS existed4" - ",known_coin_id4 AS known_coin_id4" - ",denom_pub_hash4 AS denom_hash4" - ",age_commitment_hash4 AS h_age_commitment4" - " FROM exchange_do_batch2_known_coin" - " ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16);" - ); struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (&coin[0].coin_pub), GNUNET_PQ_query_param_auto_from_type (&coin[0].denom_pub_hash), @@ -355,6 +332,28 @@ insert4 (struct PostgresClosure *pg, GNUNET_PQ_result_spec_end }; + PREPARE (pg, + "batch4_known_coin", + "SELECT" + " existed1 AS existed" + ",known_coin_id1 AS known_coin_id" + ",denom_pub_hash1 AS denom_hash" + ",age_commitment_hash1 AS h_age_commitment" + ",existed2 AS existed2" + ",known_coin_id2 AS known_coin_id2" + ",denom_pub_hash2 AS denom_hash2" + ",age_commitment_hash2 AS h_age_commitment2" + ",existed3 AS existed3" + ",known_coin_id3 AS known_coin_id3" + ",denom_pub_hash3 AS denom_hash3" + ",age_commitment_hash3 AS h_age_commitment3" + ",existed4 AS existed4" + ",known_coin_id4 AS known_coin_id4" + ",denom_pub_hash4 AS denom_hash4" + ",age_commitment_hash4 AS h_age_commitment4" + " FROM exchange_do_batch2_known_coin" + " ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16);" + ); qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, "batch4_known_coin", params, diff --git a/src/exchangedb/pg_begin_revolving_shard.c b/src/exchangedb/pg_begin_revolving_shard.c index 86cdf80fd..8d0b31a2d 100644 --- a/src/exchangedb/pg_begin_revolving_shard.c +++ b/src/exchangedb/pg_begin_revolving_shard.c @@ -164,7 +164,7 @@ TEH_PG_begin_revolving_shard (void *cls, end_row), GNUNET_PQ_result_spec_end }; - /* Used in #postgres_begin_revolving_shard() */ + PREPARE (pg, "get_open_revolving_shard", "SELECT" @@ -194,9 +194,9 @@ TEH_PG_begin_revolving_shard (void *cls, return qs; case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: { - enum GNUNET_DB_QueryStatus qs; + enum GNUNET_DB_QueryStatus qsz; struct GNUNET_TIME_Timestamp now; - struct GNUNET_PQ_QueryParam params[] = { + 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), @@ -205,8 +205,6 @@ TEH_PG_begin_revolving_shard (void *cls, }; now = GNUNET_TIME_timestamp_get (); - - /* Used in #postgres_begin_revolving_shard() */ PREPARE (pg, "reclaim_revolving_shard", "UPDATE revolving_work_shards" @@ -215,10 +213,10 @@ TEH_PG_begin_revolving_shard (void *cls, " WHERE job_name=$1" " AND start_row=$3" " AND end_row=$4"); - qs = GNUNET_PQ_eval_prepared_non_select (pg->conn, - "reclaim_revolving_shard", - params); - switch (qs) + qsz = GNUNET_PQ_eval_prepared_non_select (pg->conn, + "reclaim_revolving_shard", + iparams); + switch (qsz) { case GNUNET_DB_STATUS_HARD_ERROR: GNUNET_break (0); diff --git a/src/exchangedb/pg_begin_shard.c b/src/exchangedb/pg_begin_shard.c index 48e077990..214198534 100644 --- a/src/exchangedb/pg_begin_shard.c +++ b/src/exchangedb/pg_begin_shard.c @@ -94,9 +94,9 @@ TEH_PG_begin_shard (void *cls, continue; case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: { - enum GNUNET_DB_QueryStatus qs; + enum GNUNET_DB_QueryStatus qsz; struct GNUNET_TIME_Absolute now; - struct GNUNET_PQ_QueryParam params[] = { + 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), @@ -112,15 +112,15 @@ TEH_PG_begin_shard (void *cls, " WHERE job_name=$1" " AND start_row=$3" " AND end_row=$4"); - qs = GNUNET_PQ_eval_prepared_non_select (pg->conn, - "reclaim_shard", - params); - switch (qs) + qsz = GNUNET_PQ_eval_prepared_non_select (pg->conn, + "reclaim_shard", + iparams); + switch (qsz) { case GNUNET_DB_STATUS_HARD_ERROR: GNUNET_break (0); TEH_PG_rollback (pg); - return qs; + return qsz; case GNUNET_DB_STATUS_SOFT_ERROR: GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Serialization error on claiming open shard\n"); diff --git a/src/exchangedb/pg_commit.c b/src/exchangedb/pg_commit.c index 8c4f87c90..1ecbdb410 100644 --- a/src/exchangedb/pg_commit.c +++ b/src/exchangedb/pg_commit.c @@ -45,11 +45,9 @@ TEH_PG_commit (void *cls) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Committing transaction `%s'\n", pg->transaction_name); - /* used in #postgres_commit */ PREPARE (pg, "do_commit", "COMMIT"); - qs = GNUNET_PQ_eval_prepared_non_select (pg->conn, "do_commit", params); diff --git a/src/exchangedb/pg_do_age_withdraw.c b/src/exchangedb/pg_do_age_withdraw.c index 970e65b5d..2ac4d2ede 100644 --- a/src/exchangedb/pg_do_age_withdraw.c +++ b/src/exchangedb/pg_do_age_withdraw.c @@ -24,7 +24,7 @@ #include "taler_exchangedb_plugin.h" #include "taler_pq_lib.h" #include "taler_pq_lib.h" -#include "pg_do_batch_withdraw.h" +#include "pg_do_age_withdraw.h" #include "pg_helper.h" #include <gnunet/gnunet_time_lib.h> diff --git a/src/exchangedb/pg_do_check_deposit_idempotent.c b/src/exchangedb/pg_do_check_deposit_idempotent.c new file mode 100644 index 000000000..8a15200e0 --- /dev/null +++ b/src/exchangedb/pg_do_check_deposit_idempotent.c @@ -0,0 +1,112 @@ +/* + 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 "platform.h" +#include "taler_error_codes.h" +#include "taler_dbevents.h" +#include "taler_pq_lib.h" +#include "pg_do_check_deposit_idempotent.h" +#include "pg_helper.h" +#include "pg_compute_shard.h" + + +enum GNUNET_DB_QueryStatus +TEH_PG_do_check_deposit_idempotent ( + void *cls, + const struct TALER_EXCHANGEDB_BatchDeposit *bd, + struct GNUNET_TIME_Timestamp *exchange_timestamp, + bool *is_idempotent) +{ + struct PostgresClosure *pg = cls; + uint64_t deposit_shard = TEH_PG_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 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), + /* to create entry in wire_targets */ + GNUNET_PQ_query_param_string (bd->receiver_wire_account), + /* arrays for coin_deposits */ + GNUNET_PQ_query_param_array_ptrs_auto_from_type (bd->num_cdis, + coin_pubs, + pg->conn), + GNUNET_PQ_query_param_array_ptrs_auto_from_type (bd->num_cdis, + coin_sigs, + pg->conn), + TALER_PQ_query_param_array_amount (bd->num_cdis, + amounts_with_fee, + pg->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; + + 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 (pg, + "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,$16);"); + qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, + "call_check_deposit_idempotent", + params, + rs); + GNUNET_PQ_cleanup_query_params_closures (params); + return qs; +} diff --git a/src/exchangedb/pg_do_check_deposit_idempotent.h b/src/exchangedb/pg_do_check_deposit_idempotent.h new file mode 100644 index 000000000..8aa00bba6 --- /dev/null +++ b/src/exchangedb/pg_do_check_deposit_idempotent.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 exchangedb/pg_do_check_deposit_idempotent.h + * @brief implementation of the do_check_deposit_idempotent function for Postgres + * @author Christian Grothoff + */ +#ifndef PG_DO_CHECK_DEPOSIT_IDEMPOTENT_H +#define PG_DO_CHECK_DEPOSIT_IDEMPOTENT_H + +#include "taler_util.h" +#include "taler_json_lib.h" +#include "taler_exchangedb_plugin.h" + + +/** + * 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 +TEH_PG_do_check_deposit_idempotent ( + void *cls, + const struct TALER_EXCHANGEDB_BatchDeposit *bd, + struct GNUNET_TIME_Timestamp *exchange_timestamp, + bool *is_idempotent); + +#endif diff --git a/src/exchangedb/pg_get_coin_transactions.c b/src/exchangedb/pg_get_coin_transactions.c index b2db935a5..5a9157dcd 100644 --- a/src/exchangedb/pg_get_coin_transactions.c +++ b/src/exchangedb/pg_get_coin_transactions.c @@ -807,6 +807,7 @@ handle_history_entry (void *cls, enum GNUNET_DB_QueryStatus TEH_PG_get_coin_transactions ( void *cls, + bool begin_transaction, const struct TALER_CoinSpendPublicKeyP *coin_pub, uint64_t start_off, uint64_t etag_in, @@ -1010,7 +1011,7 @@ TEH_PG_get_coin_transactions ( " ON (denoms.denominations_serial = coins.denominations_serial)" " WHERE rcp.recoup_uuid=$2" " AND coins.coin_pub=$1;"); - /* Used in #postgres_get_coin_transactions() to obtain recoup transactions + /* Used to obtain recoup transactions for a refreshed coin */ PREPARE (pg, "recoup_by_refreshed_coin", @@ -1062,12 +1063,15 @@ TEH_PG_get_coin_transactions ( GNUNET_PQ_result_spec_end }; - if (GNUNET_OK != - TEH_PG_start_read_committed (pg, - "get-coin-transactions")) + if (begin_transaction) { - GNUNET_break (0); - return GNUNET_DB_STATUS_HARD_ERROR; + if (GNUNET_OK != + TEH_PG_start_read_committed (pg, + "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 */ @@ -1079,13 +1083,16 @@ TEH_PG_get_coin_transactions ( switch (qs) { case GNUNET_DB_STATUS_HARD_ERROR: - TEH_PG_rollback (pg); + if (begin_transaction) + TEH_PG_rollback (pg); return qs; case GNUNET_DB_STATUS_SOFT_ERROR: - TEH_PG_rollback (pg); + if (begin_transaction) + TEH_PG_rollback (pg); continue; case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - TEH_PG_rollback (pg); + if (begin_transaction) + TEH_PG_rollback (pg); return qs; case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: *etag_out = end; @@ -1107,21 +1114,29 @@ TEH_PG_get_coin_transactions ( switch (qs) { case GNUNET_DB_STATUS_HARD_ERROR: - TEH_PG_rollback (pg); + if (begin_transaction) + TEH_PG_rollback (pg); return qs; case GNUNET_DB_STATUS_SOFT_ERROR: - TEH_PG_rollback (pg); + if (begin_transaction) + TEH_PG_rollback (pg); continue; default: break; } if (chc.failed) { - TEH_PG_rollback (pg); + if (begin_transaction) + TEH_PG_rollback (pg); TEH_COMMON_free_coin_transaction_list (pg, chc.head); return GNUNET_DB_STATUS_SOFT_ERROR; } + if (! begin_transaction) + { + *tlp = chc.head; + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; + } qs = TEH_PG_commit (pg); switch (qs) { diff --git a/src/exchangedb/pg_get_coin_transactions.h b/src/exchangedb/pg_get_coin_transactions.h index 46e32e094..c844a51f2 100644 --- a/src/exchangedb/pg_get_coin_transactions.h +++ b/src/exchangedb/pg_get_coin_transactions.h @@ -34,6 +34,7 @@ * 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 @@ -49,6 +50,7 @@ enum GNUNET_DB_QueryStatus TEH_PG_get_coin_transactions ( void *cls, + bool begin_transaction, const struct TALER_CoinSpendPublicKeyP *coin_pub, uint64_t start_off, uint64_t etag_in, diff --git a/src/exchangedb/pg_get_kyc_rules.c b/src/exchangedb/pg_get_kyc_rules.c index 34b06d366..8f7967273 100644 --- a/src/exchangedb/pg_get_kyc_rules.c +++ b/src/exchangedb/pg_get_kyc_rules.c @@ -30,6 +30,10 @@ enum GNUNET_DB_QueryStatus TEH_PG_get_kyc_rules ( void *cls, const struct TALER_PaytoHashP *h_payto, + bool *no_account_pub, + union TALER_AccountPublicKeyP *account_pub, + bool *no_reserve_pub, + struct TALER_ReservePublicKeyP *reserve_pub, json_t **jrules) { struct PostgresClosure *pg = cls; @@ -41,19 +45,46 @@ TEH_PG_get_kyc_rules ( GNUNET_PQ_query_param_end }; struct GNUNET_PQ_ResultSpec rs[] = { - TALER_PQ_result_spec_json ("jnew_rules", - jrules), + 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 (pg, "get_kyc_rules", "SELECT" - " jnew_rules" - " FROM legitimization_outcomes" - " WHERE h_payto=$1" - " AND expiration_time >= $2" - " AND is_active;"); + " wt.target_pub" + " ,lo.jnew_rules" + " ,ri.reserve_pub" + " FROM wire_targets wt" + " LEFT JOIN reserves_in ri" + " ON (ri.wire_source_h_payto = wt.wire_target_h_payto)" + " LEFT JOIN legitimization_outcomes lo" + " ON (lo.h_payto = wt.wire_target_h_payto)" + " WHERE wt.wire_target_h_payto=$1" + " AND COALESCE(lo.expiration_time >= $2, TRUE)" + " AND COALESCE(lo.is_active, TRUE)" + " ORDER BY ri.execution_date DESC" + " LIMIT 1;"); return GNUNET_PQ_eval_prepared_singleton_select ( pg->conn, "get_kyc_rules", diff --git a/src/exchangedb/pg_get_kyc_rules.h b/src/exchangedb/pg_get_kyc_rules.h index 9b0e2d68d..9473fdc2c 100644 --- a/src/exchangedb/pg_get_kyc_rules.h +++ b/src/exchangedb/pg_get_kyc_rules.h @@ -31,6 +31,13 @@ * * @param cls the @e cls of this struct with the plugin-specific state * @param h_payto account identifier + * @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 @@ -39,6 +46,10 @@ enum GNUNET_DB_QueryStatus TEH_PG_get_kyc_rules ( void *cls, const struct TALER_PaytoHashP *h_payto, + bool *no_account_pub, + union TALER_AccountPublicKeyP *account_pub, + bool *no_reserve_pub, + struct TALER_ReservePublicKeyP *reserve_pub, json_t **jrules); #endif diff --git a/src/exchangedb/pg_helper.h b/src/exchangedb/pg_helper.h index 56112456c..aeb1eb02e 100644 --- a/src/exchangedb/pg_helper.h +++ b/src/exchangedb/pg_helper.h @@ -100,27 +100,27 @@ struct PostgresClosure * @param name name to prepare the statement under * @param sql actual SQL text */ -#define PREPARE(pg,name,sql) \ +#define PREPARE(pg,name,sql) \ do { \ static struct { \ unsigned long long cnt; \ struct PostgresClosure *pg; \ - } preps[2]; /* 2 ctrs for taler-auditor-sync*/ \ - unsigned int off = 0; \ - \ - while ( (NULL != preps[off].pg) && \ - (pg != preps[off].pg) && \ - (off < sizeof(preps) / sizeof(*preps)) ) \ - off++; \ - GNUNET_assert (off < \ - sizeof(preps) / sizeof(*preps)); \ - if (preps[off].cnt < pg->prep_gen) \ + } preps_[2]; /* 2 ctrs for taler-auditor-sync*/ \ + unsigned int off_ = 0; \ + \ + while ( (NULL != preps_[off_].pg) && \ + (pg != preps_[off_].pg) && \ + (off_ < sizeof(preps_) / sizeof(*preps_)) ) \ + off_++; \ + GNUNET_assert (off_ < \ + sizeof(preps_) / sizeof(*preps_)); \ + if (preps_[off_].cnt < pg->prep_gen) \ { \ struct GNUNET_PQ_PreparedStatement ps[] = { \ GNUNET_PQ_make_prepare (name, sql), \ GNUNET_PQ_PREPARED_STATEMENT_END \ }; \ - \ + \ if (GNUNET_OK != \ GNUNET_PQ_prepare_statements (pg->conn, \ ps)) \ @@ -128,8 +128,8 @@ struct PostgresClosure GNUNET_break (0); \ return GNUNET_DB_STATUS_HARD_ERROR; \ } \ - preps[off].pg = pg; \ - preps[off].cnt = pg->prep_gen; \ + preps_[off_].pg = pg; \ + preps_[off_].cnt = pg->prep_gen; \ } \ } while (0) diff --git a/src/exchangedb/pg_inject_auditor_triggers.c b/src/exchangedb/pg_inject_auditor_triggers.c index 562a1a22c..3b27908c9 100644 --- a/src/exchangedb/pg_inject_auditor_triggers.c +++ b/src/exchangedb/pg_inject_auditor_triggers.c @@ -24,6 +24,7 @@ #include "taler_pq_lib.h" #include "pg_gc.h" #include "pg_helper.h" +#include "pg_inject_auditor_triggers.h" /** diff --git a/src/exchangedb/pg_insert_active_legitimization_measure.c b/src/exchangedb/pg_insert_active_legitimization_measure.c new file mode 100644 index 000000000..33c702ef4 --- /dev/null +++ b/src/exchangedb/pg_insert_active_legitimization_measure.c @@ -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 exchangedb/pg_insert_active_legitimization_measure.c + * @brief Implementation of the insert_active_legitimization_measure function for Postgres + * @author Christian Grothoff + */ +#include "platform.h" +#include "taler_error_codes.h" +#include "taler_dbevents.h" +#include "taler_pq_lib.h" +#include "pg_insert_active_legitimization_measure.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +TEH_PG_insert_active_legitimization_measure ( + void *cls, + const struct TALER_AccountAccessTokenP *access_token, + const json_t *jmeasures, + uint64_t *legitimization_measure_serial_id) +{ + struct PostgresClosure *pg = cls; + 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 (pg, + "do_insert_active_legitimization_measure", + "SELECT" + " out_legitimization_measure_serial_id" + " FROM exchange_do_insert_active_legitimization_measure" + "($1, $2, $3);"); + return GNUNET_PQ_eval_prepared_singleton_select ( + pg->conn, + "do_insert_active_legitimization_measure", + params, + rs); +} diff --git a/src/exchangedb/pg_insert_active_legitimization_measure.h b/src/exchangedb/pg_insert_active_legitimization_measure.h new file mode 100644 index 000000000..09b558d83 --- /dev/null +++ b/src/exchangedb/pg_insert_active_legitimization_measure.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 exchangedb/pg_insert_active_legitimization_measure.h + * @brief implementation of the insert_active_legitimization_measure function for Postgres + * @author Christian Grothoff + */ +#ifndef PG_INSERT_ACTIVE_LEGITIMIZATION_MEASURE_H +#define PG_INSERT_ACTIVE_LEGITIMIZATION_MEASURE_H + +#include "taler_util.h" +#include "taler_json_lib.h" +#include "taler_exchangedb_plugin.h" + +/** + * 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 +TEH_PG_insert_active_legitimization_measure ( + void *cls, + const struct TALER_AccountAccessTokenP *access_token, + const json_t *jmeasures, + uint64_t *legitimization_measure_serial_id); + + +#endif diff --git a/src/exchangedb/pg_insert_aml_decision.c b/src/exchangedb/pg_insert_aml_decision.c index 17edb9873..4da711577 100644 --- a/src/exchangedb/pg_insert_aml_decision.c +++ b/src/exchangedb/pg_insert_aml_decision.c @@ -30,6 +30,7 @@ enum GNUNET_DB_QueryStatus TEH_PG_insert_aml_decision ( void *cls, + const char *payto_uri, const struct TALER_PaytoHashP *h_payto, struct GNUNET_TIME_Timestamp decision_time, struct GNUNET_TIME_Timestamp expiration_time, @@ -54,6 +55,9 @@ TEH_PG_insert_aml_decision ( char *notify_s = GNUNET_PQ_get_event_notify_channel (&rep.header); struct GNUNET_PQ_QueryParam params[] = { + NULL == payto_uri + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (payto_uri), GNUNET_PQ_query_param_auto_from_type (h_payto), GNUNET_PQ_query_param_timestamp (&decision_time), GNUNET_PQ_query_param_timestamp (&expiration_time), @@ -92,7 +96,7 @@ TEH_PG_insert_aml_decision ( ",out_account_unknown" ",out_last_date" " FROM exchange_do_insert_aml_decision" - "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12);"); + "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13);"); qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, "do_insert_aml_decision", params, diff --git a/src/exchangedb/pg_insert_aml_decision.h b/src/exchangedb/pg_insert_aml_decision.h index cdb8d66b3..15441b4d4 100644 --- a/src/exchangedb/pg_insert_aml_decision.h +++ b/src/exchangedb/pg_insert_aml_decision.h @@ -31,6 +31,8 @@ * 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 @@ -52,6 +54,7 @@ enum GNUNET_DB_QueryStatus TEH_PG_insert_aml_decision ( void *cls, + const char *payto_uri, const struct TALER_PaytoHashP *h_payto, struct GNUNET_TIME_Timestamp decision_time, struct GNUNET_TIME_Timestamp expiration_time, diff --git a/src/exchangedb/pg_insert_kyc_requirement_process.c b/src/exchangedb/pg_insert_kyc_requirement_process.c index 33e4b9f70..bbb2efc9c 100644 --- a/src/exchangedb/pg_insert_kyc_requirement_process.c +++ b/src/exchangedb/pg_insert_kyc_requirement_process.c @@ -61,7 +61,7 @@ TEH_PG_insert_kyc_requirement_process ( }; PREPARE (pg, - "insert_legitimization_process", + "insert_kyc_requirement_process", "INSERT INTO legitimization_processes" " (h_payto" " ,start_time" @@ -72,10 +72,17 @@ TEH_PG_insert_kyc_requirement_process ( " ,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 ( pg->conn, - "insert_legitimization_process", + "insert_kyc_requirement_process", params, rs); } diff --git a/src/exchangedb/pg_insert_records_by_table.c b/src/exchangedb/pg_insert_records_by_table.c index 097e6275e..344c7d84c 100644 --- a/src/exchangedb/pg_insert_records_by_table.c +++ b/src/exchangedb/pg_insert_records_by_table.c @@ -172,10 +172,14 @@ irbt_cb_table_wire_targets (struct PostgresClosure *pg, struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_uint64 (&td->serial), GNUNET_PQ_query_param_auto_from_type (&payto_hash), - GNUNET_PQ_query_param_auto_from_type ( - &td->details.wire_targets.target_token), GNUNET_PQ_query_param_string ( td->details.wire_targets.payto_uri), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.wire_targets.access_token), + td->details.wire_targets.no_account + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_auto_from_type ( + &td->details.wire_targets.target_pub), GNUNET_PQ_query_param_end }; @@ -187,10 +191,11 @@ irbt_cb_table_wire_targets (struct PostgresClosure *pg, "INSERT INTO wire_targets" "(wire_target_serial_id" ",wire_target_h_payto" - ",target_token" ",payto_uri" + ",access_token" + ",target_pub" ") VALUES " - "($1, $2, $3, $4);"); + "($1, $2, $3, $4, $5);"); return GNUNET_PQ_eval_prepared_non_select (pg->conn, "insert_into_table_wire_targets", params); @@ -1014,8 +1019,8 @@ irbt_cb_table_batch_deposits (struct PostgresClosure *pg, ",wallet_data_hash" ",wire_salt" ",wire_target_h_payto" - ",policy_details_serial_id" ",policy_blocked" + ",policy_details_serial_id" ") VALUES " "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10," " $11, $12, $13);"); diff --git a/src/exchangedb/pg_iterate_reserve_close_info.c b/src/exchangedb/pg_iterate_reserve_close_info.c index ff0a813c3..6b4e72d69 100644 --- a/src/exchangedb/pg_iterate_reserve_close_info.c +++ b/src/exchangedb/pg_iterate_reserve_close_info.c @@ -22,7 +22,7 @@ #include "taler_error_codes.h" #include "taler_dbevents.h" #include "taler_pq_lib.h" -#include "pg_insert_reserve_open_deposit.h" +#include "pg_iterate_reserve_close_info.h" #include "pg_helper.h" /** diff --git a/src/exchangedb/pg_kycauth_in_insert.c b/src/exchangedb/pg_kycauth_in_insert.c index aafbe2acb..2f2ebcec9 100644 --- a/src/exchangedb/pg_kycauth_in_insert.c +++ b/src/exchangedb/pg_kycauth_in_insert.c @@ -38,27 +38,42 @@ TEH_PG_kycauth_in_insert ( { struct PostgresClosure *pg = cls; struct TALER_PaytoHashP h_payto; - 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 (pg->conn, - credit_amount), - GNUNET_PQ_query_param_auto_from_type (&h_payto), - GNUNET_PQ_query_param_string (debit_account_uri), - GNUNET_PQ_query_param_string (section_name), - GNUNET_PQ_query_param_timestamp (&execution_date), - GNUNET_PQ_query_param_end - }; - PREPARE (pg, - "kycauth_in_insert", - "CALL" - " exchange_do_kycauth_in_insert" - " ($1,$2,$3,$4,$5,$6,$7);"); TALER_payto_hash (debit_account_uri, &h_payto); - return GNUNET_PQ_eval_prepared_non_select ( - pg->conn, - "kycauth_in_insert", - params); + + { + 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 (account_pub), + GNUNET_PQ_query_param_uint64 (&serial_id), + TALER_PQ_query_param_amount (pg->conn, + credit_amount), + GNUNET_PQ_query_param_auto_from_type (&h_payto), + GNUNET_PQ_query_param_string (debit_account_uri), + 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 (pg, + "kycauth_in_insert", + "CALL" + " exchange_do_kycauth_in_insert" + " ($1,$2,$3,$4,$5,$6,$7,$8);"); + qs = GNUNET_PQ_eval_prepared_non_select ( + pg->conn, + "kycauth_in_insert", + params); + GNUNET_free (notify_s); + return qs; + } } diff --git a/src/exchangedb/pg_lookup_completed_legitimization.c b/src/exchangedb/pg_lookup_completed_legitimization.c new file mode 100644 index 000000000..3a500dc32 --- /dev/null +++ b/src/exchangedb/pg_lookup_completed_legitimization.c @@ -0,0 +1,94 @@ +/* + 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_completed_legitimization.c + * @brief Implementation of the lookup_pending_legitimization function for Postgres + * @author Christian Grothoff + */ +#include "platform.h" +#include "taler_error_codes.h" +#include "taler_dbevents.h" +#include "taler_pq_lib.h" +#include "pg_lookup_completed_legitimization.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +TEH_PG_lookup_completed_legitimization ( + void *cls, + uint64_t legitimization_measure_serial_id, + uint32_t measure_index, + struct TALER_AccountAccessTokenP *access_token, + struct TALER_PaytoHashP *h_payto, + json_t **jmeasures, + bool *is_finished, + size_t *encrypted_attributes_len, + void **encrypted_attributes + ) +{ + struct PostgresClosure *pg = cls; + 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 ( + "wire_target_h_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_end + }; + + *encrypted_attributes_len = 0; + *encrypted_attributes = NULL; + PREPARE (pg, + "lookup_completed_legitimization", + "SELECT " + " lm.jmeasures" + ",wt.wire_target_h_payto" + ",lm.access_token" + ",lm.is_finished" + ",ka.encrypted_attributes" + " FROM legitimization_measures lm" + " JOIN wire_targets wt" + " ON (lm.access_token = wt.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 ( + pg->conn, + "lookup_completed_legitimization", + params, + rs); +} diff --git a/src/exchangedb/pg_lookup_completed_legitimization.h b/src/exchangedb/pg_lookup_completed_legitimization.h new file mode 100644 index 000000000..1bc16c2ac --- /dev/null +++ b/src/exchangedb/pg_lookup_completed_legitimization.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/> + */ +/** + * @file exchangedb/pg_lookup_pending_legitimization.h + * @brief implementation of the lookup_pending_legitimization function for Postgres + * @author Christian Grothoff + */ +#ifndef PG_LOOKUP_COMPLETED_LEGITIMIZATION_H +#define PG_LOOKUP_COMPLETED_LEGITIMIZATION_H + +#include "taler_util.h" +#include "taler_json_lib.h" +#include "taler_exchangedb_plugin.h" + + +/** + * 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] 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 +TEH_PG_lookup_completed_legitimization ( + void *cls, + uint64_t legitimization_measure_serial_id, + uint32_t measure_index, + struct TALER_AccountAccessTokenP *access_token, + struct TALER_PaytoHashP *h_payto, + json_t **jmeasures, + bool *is_finished, + size_t *encrypted_attributes_len, + void **encrypted_attributes); + +#endif diff --git a/src/exchangedb/pg_lookup_kyc_requirement_by_row.c b/src/exchangedb/pg_lookup_kyc_requirement_by_row.c index e4a5ecbca..66d083b8d 100644 --- a/src/exchangedb/pg_lookup_kyc_requirement_by_row.c +++ b/src/exchangedb/pg_lookup_kyc_requirement_by_row.c @@ -29,7 +29,7 @@ enum GNUNET_DB_QueryStatus TEH_PG_lookup_kyc_requirement_by_row ( void *cls, - uint64_t requirement_row, + const struct TALER_PaytoHashP *h_payto, union TALER_AccountPublicKeyP *account_pub, struct TALER_ReservePublicKeyP *reserve_pub, struct TALER_AccountAccessTokenP *access_token, @@ -39,7 +39,7 @@ TEH_PG_lookup_kyc_requirement_by_row ( { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&requirement_row), + GNUNET_PQ_query_param_auto_from_type (h_payto), GNUNET_PQ_query_param_end }; bool not_found; diff --git a/src/exchangedb/pg_lookup_kyc_requirement_by_row.h b/src/exchangedb/pg_lookup_kyc_requirement_by_row.h index 05bab2e54..8bf6c38d9 100644 --- a/src/exchangedb/pg_lookup_kyc_requirement_by_row.h +++ b/src/exchangedb/pg_lookup_kyc_requirement_by_row.h @@ -30,7 +30,7 @@ * Lookup KYC requirement. * * @param cls closure - * @param requirement_row identifies requirement to look up (in legitimization_measures table) + * @param h_payto identifies account to look up requirement for * @param[out] account_pub set to public key of the account * needed to authorize access, all zeros if not known * @param[out] reserve_pub set to last reserve public key @@ -50,7 +50,7 @@ enum GNUNET_DB_QueryStatus TEH_PG_lookup_kyc_requirement_by_row ( void *cls, - uint64_t requirement_row, + const struct TALER_PaytoHashP *h_payto, union TALER_AccountPublicKeyP *account_pub, struct TALER_ReservePublicKeyP *reserve_pub, struct TALER_AccountAccessTokenP *access_token, diff --git a/src/exchangedb/pg_lookup_pending_legitimization.c b/src/exchangedb/pg_lookup_pending_legitimization.c index 11e884349..8475d3963 100644 --- a/src/exchangedb/pg_lookup_pending_legitimization.c +++ b/src/exchangedb/pg_lookup_pending_legitimization.c @@ -33,10 +33,7 @@ TEH_PG_lookup_pending_legitimization ( struct TALER_AccountAccessTokenP *access_token, struct TALER_PaytoHashP *h_payto, json_t **jmeasures, - bool *is_finished, - size_t *encrypted_attributes_len, - void **encrypted_attributes - ) + bool *is_finished) { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { @@ -56,17 +53,9 @@ TEH_PG_lookup_pending_legitimization ( 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_end }; - *encrypted_attributes_len = 0; - *encrypted_attributes = NULL; PREPARE (pg, "lookup_pending_legitimization", "SELECT " @@ -74,14 +63,9 @@ TEH_PG_lookup_pending_legitimization ( ",wt.wire_target_h_payto" ",lm.access_token" ",lm.is_finished" - ",ka.encrypted_attributes" " FROM legitimization_measures lm" " JOIN wire_targets wt" " ON (lm.access_token = wt.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;"); return GNUNET_PQ_eval_prepared_singleton_select ( pg->conn, diff --git a/src/exchangedb/pg_lookup_pending_legitimization.h b/src/exchangedb/pg_lookup_pending_legitimization.h index d1c4e0b59..eaf6a60d7 100644 --- a/src/exchangedb/pg_lookup_pending_legitimization.h +++ b/src/exchangedb/pg_lookup_pending_legitimization.h @@ -40,11 +40,6 @@ * 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 @@ -54,8 +49,6 @@ TEH_PG_lookup_pending_legitimization ( struct TALER_AccountAccessTokenP *access_token, struct TALER_PaytoHashP *h_payto, json_t **jmeasures, - bool *is_finished, - size_t *encrypted_attributes_len, - void **encrypted_attributes); + bool *is_finished); #endif diff --git a/src/exchangedb/pg_lookup_records_by_table.c b/src/exchangedb/pg_lookup_records_by_table.c index 52f64cf91..e8c6f8fa1 100644 --- a/src/exchangedb/pg_lookup_records_by_table.c +++ b/src/exchangedb/pg_lookup_records_by_table.c @@ -215,7 +215,12 @@ lrbt_cb_table_wire_targets (void *cls, &td.serial), GNUNET_PQ_result_spec_auto_from_type ( "access_token", - &td.details.wire_targets.target_token), + &td.details.wire_targets.access_token), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ( + "target_pub", + &td.details.wire_targets.target_pub), + &td.details.wire_targets.no_account), GNUNET_PQ_result_spec_string ( "payto_uri", &td.details.wire_targets.payto_uri), @@ -3117,6 +3122,7 @@ TEH_PG_lookup_records_by_table (void *cls, "SELECT" " wire_target_serial_id AS serial" ",access_token" + ",target_pub" ",payto_uri" " FROM wire_targets" " WHERE wire_target_serial_id > $1" diff --git a/src/exchangedb/pg_insert_kyc_requirement_for_account.c b/src/exchangedb/pg_lookup_rules_by_access_token.c index 776b79ff8..0bfdeb5d2 100644 --- a/src/exchangedb/pg_insert_kyc_requirement_for_account.c +++ b/src/exchangedb/pg_lookup_rules_by_access_token.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + 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 @@ -14,54 +14,57 @@ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ /** - * @file exchangedb/pg_insert_kyc_requirement_for_account.c - * @brief Implementation of the insert_kyc_requirement_for_account function for Postgres + * @file exchangedb/pg_lookup_rules_by_access_token.c + * @brief Implementation of the lookup_rules_by_access_token function for Postgres * @author Christian Grothoff */ #include "platform.h" #include "taler_error_codes.h" #include "taler_dbevents.h" #include "taler_pq_lib.h" -#include "pg_insert_kyc_requirement_for_account.h" +#include "pg_lookup_rules_by_access_token.h" #include "pg_helper.h" + enum GNUNET_DB_QueryStatus -TEH_PG_insert_kyc_requirement_for_account ( +TEH_PG_lookup_rules_by_access_token ( void *cls, - const char *provider_name, const struct TALER_PaytoHashP *h_payto, - const struct TALER_ReservePublicKeyP *reserve_pub, - uint64_t *requirement_row) + json_t **jnew_rules, + uint64_t *rowid) { struct PostgresClosure *pg = cls; + struct GNUNET_TIME_Absolute now; struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (h_payto), - (NULL == reserve_pub) - ? GNUNET_PQ_query_param_null () - : GNUNET_PQ_query_param_auto_from_type (reserve_pub), - GNUNET_PQ_query_param_string (provider_name), + GNUNET_PQ_query_param_absolute_time (&now), GNUNET_PQ_query_param_end }; struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_uint64 ("legitimization_requirement_serial_id", - requirement_row), + TALER_PQ_result_spec_json ( + "jnew_rules", + jnew_rules), + GNUNET_PQ_result_spec_uint64 ( + "row_id", + rowid), GNUNET_PQ_result_spec_end }; - /* Used in #postgres_insert_kyc_requirement_for_account() */ + PREPARE (pg, - "insert_legitimization_requirement", - "INSERT INTO legitimization_requirements" - " (h_payto" - " ,reserve_pub" - " ,required_checks" - " ) VALUES " - " ($1, $2, $3)" - " ON CONFLICT (h_payto,required_checks) " - " DO UPDATE SET h_payto=$1" /* syntax requirement: dummy op */ - " RETURNING legitimization_requirement_serial_id"); + "lookup_rules_by_access_token", + "SELECT" + " jnew_rules" + ",outcome_serial_id AS row_id" + " FROM legitimization_outcomes" + " WHERE h_payto=$1" + " AND expiration_time>$2" + " AND is_active" + " ORDER BY expiration_time DESC" + " LIMIT 1;"); + now = GNUNET_TIME_absolute_get (); return GNUNET_PQ_eval_prepared_singleton_select ( pg->conn, - "insert_legitimization_requirement", + "lookup_rules_by_access_token", params, rs); } diff --git a/src/exchangedb/pg_insert_kyc_requirement_for_account.h b/src/exchangedb/pg_lookup_rules_by_access_token.h index db95502fb..e1824382c 100644 --- a/src/exchangedb/pg_insert_kyc_requirement_for_account.h +++ b/src/exchangedb/pg_lookup_rules_by_access_token.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + 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 @@ -14,34 +14,31 @@ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ /** - * @file exchangedb/pg_insert_kyc_requirement_for_account.h - * @brief implementation of the insert_kyc_requirement_for_account function for Postgres + * @file exchangedb/pg_lookup_rules_by_access_token.h + * @brief implementation of the lookup_rules_by_access_token function for Postgres * @author Christian Grothoff */ -#ifndef PG_INSERT_KYC_REQUIREMENT_FOR_ACCOUNT_H -#define PG_INSERT_KYC_REQUIREMENT_FOR_ACCOUNT_H +#ifndef PG_LOOKUP_RULES_BY_ACCESS_TOKEN_H +#define PG_LOOKUP_RULES_BY_ACCESS_TOKEN_H #include "taler_util.h" #include "taler_json_lib.h" #include "taler_exchangedb_plugin.h" - /** - * Insert KYC requirement for @a h_payto account into table. + * Lookup KYC rules by account access token. * * @param cls closure - * @param provider_name provider that must be checked - * @param h_payto account that must be KYC'ed - * @param reserve_pub if the account is a reserve, its public key. Maybe NULL - * @param[out] requirement_row set to legitimization requirement row for this check + * @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 -TEH_PG_insert_kyc_requirement_for_account ( +TEH_PG_lookup_rules_by_access_token ( void *cls, - const char *provider_name, const struct TALER_PaytoHashP *h_payto, - const struct TALER_ReservePublicKeyP *reserve_pub, - uint64_t *requirement_row); + json_t **jnew_rules, + uint64_t *rowid); #endif diff --git a/src/exchangedb/pg_lookup_transfer_by_deposit.c b/src/exchangedb/pg_lookup_transfer_by_deposit.c index ffa762477..d326feff7 100644 --- a/src/exchangedb/pg_lookup_transfer_by_deposit.c +++ b/src/exchangedb/pg_lookup_transfer_by_deposit.c @@ -38,7 +38,8 @@ TEH_PG_lookup_transfer_by_deposit ( struct GNUNET_TIME_Timestamp *exec_time, struct TALER_Amount *amount_with_fee, struct TALER_Amount *deposit_fee, - struct TALER_EXCHANGEDB_KycStatus *kyc) + struct TALER_EXCHANGEDB_KycStatus *kyc, + union TALER_AccountPublicKeyP *account_pub) { struct PostgresClosure *pg = cls; enum GNUNET_DB_QueryStatus qs; @@ -63,6 +64,10 @@ TEH_PG_lookup_transfer_by_deposit ( 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 }; @@ -78,6 +83,7 @@ TEH_PG_lookup_transfer_by_deposit ( ",cdep.amount_with_fee" ",bdep.wire_salt" ",wt.payto_uri" + ",wt.target_pub" ",denom.fee_deposit" " FROM coin_deposits cdep" " JOIN batch_deposits bdep" @@ -101,6 +107,8 @@ TEH_PG_lookup_transfer_by_deposit ( "lookup_deposit_wtid", params, rs); + if (0 > qs) + return qs; if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) { struct TALER_MerchantWireHashP wh; @@ -120,8 +128,6 @@ TEH_PG_lookup_transfer_by_deposit ( qs = GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; GNUNET_PQ_cleanup_result (rs); } - if (0 > qs) - return qs; *pending = true; memset (wtid, 0, @@ -182,6 +188,8 @@ TEH_PG_lookup_transfer_by_deposit ( "get_deposit_without_wtid", params, rs2); + if (0 > qs) + return qs; if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) { struct TALER_MerchantWireHashP wh; diff --git a/src/exchangedb/pg_lookup_transfer_by_deposit.h b/src/exchangedb/pg_lookup_transfer_by_deposit.h index ff5554dcc..2a5340d4f 100644 --- a/src/exchangedb/pg_lookup_transfer_by_deposit.h +++ b/src/exchangedb/pg_lookup_transfer_by_deposit.h @@ -42,6 +42,7 @@ * @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 @@ -56,6 +57,7 @@ TEH_PG_lookup_transfer_by_deposit ( struct GNUNET_TIME_Timestamp *exec_time, struct TALER_Amount *amount_with_fee, struct TALER_Amount *deposit_fee, - struct TALER_EXCHANGEDB_KycStatus *kyc); + struct TALER_EXCHANGEDB_KycStatus *kyc, + union TALER_AccountPublicKeyP *account_pub); #endif diff --git a/src/exchangedb/pg_preflight.c b/src/exchangedb/pg_preflight.c index 4533c9a97..c30a9651e 100644 --- a/src/exchangedb/pg_preflight.c +++ b/src/exchangedb/pg_preflight.c @@ -24,16 +24,7 @@ #include "taler_pq_lib.h" #include "pg_preflight.h" #include "pg_helper.h" - - -/** - * Connect to the database if the connection does not exist yet. - * - * @param pg the plugin-specific state - * @return #GNUNET_OK on success - */ -enum GNUNET_GenericReturnValue -TEH_PG_internal_setup (struct PostgresClosure *pg); +#include "plugin_exchangedb_postgres.h" enum GNUNET_GenericReturnValue diff --git a/src/exchangedb/pg_reserves_in_insert.c b/src/exchangedb/pg_reserves_in_insert.c index 21734942a..95e488771 100644 --- a/src/exchangedb/pg_reserves_in_insert.c +++ b/src/exchangedb/pg_reserves_in_insert.c @@ -327,18 +327,18 @@ TEH_PG_reserves_in_insert ( &duplicate), GNUNET_PQ_result_spec_end }; - enum GNUNET_DB_QueryStatus qs; + enum GNUNET_DB_QueryStatus qsi; - qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, - "reserves_update", - params, - rs); - if (qs < 0) + qsi = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, + "reserves_update", + params, + rs); + if (qsi < 0) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to update reserves (%d)\n", - qs); - results[i] = qs; + qsi); + results[i] = qsi; goto finished; } results[i] = duplicate diff --git a/src/exchangedb/pg_select_aggregations_above_serial.c b/src/exchangedb/pg_select_aggregations_above_serial.c index 52d202702..56f99b022 100644 --- a/src/exchangedb/pg_select_aggregations_above_serial.c +++ b/src/exchangedb/pg_select_aggregations_above_serial.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2023 Taler Systems SA + 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 @@ -67,12 +67,16 @@ aggregation_serial_helper_cb (void *cls, unsigned int num_results) { struct AggregationSerialContext *dsc = cls; + struct PostgresClosure *pg = dsc->pg; 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", @@ -90,6 +94,7 @@ aggregation_serial_helper_cb (void *cls, return; } dsc->cb (dsc->cb_cls, + &amount, tracking_rowid, batch_deposit_serial_id); GNUNET_PQ_cleanup_result (rs); @@ -123,9 +128,8 @@ TEH_PG_select_aggregations_above_serial ( "SELECT" " aggregation_serial_id" ",batch_deposit_serial_id" - " FROM aggregation_tracking" - " WHERE aggregation_serial_id>=$1" - " ORDER BY aggregation_serial_id ASC;"); + ",total_amount" + " FROM exchange_do_select_aggregations_above_serial($1);"); qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, "select_aggregations_above_serial", params, diff --git a/src/exchangedb/pg_select_aml_attributes.c b/src/exchangedb/pg_select_aml_attributes.c index 09136e2fd..6aeb74ffd 100644 --- a/src/exchangedb/pg_select_aml_attributes.c +++ b/src/exchangedb/pg_select_aml_attributes.c @@ -72,17 +72,12 @@ handle_aml_attributes (void *cls, for (unsigned int i = 0; i<num_results; i++) { uint64_t rowid; - char *provider_name; struct GNUNET_TIME_Timestamp collection_time; 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_allow_null ( - GNUNET_PQ_result_spec_string ("provider", - &provider_name), - NULL), GNUNET_PQ_result_spec_timestamp ("collection_time", &collection_time), GNUNET_PQ_result_spec_variable_size ("encrypted_attributes", @@ -103,7 +98,6 @@ handle_aml_attributes (void *cls, ctx->cb (ctx->cb_cls, rowid, - provider_name, collection_time, enc_attributes_size, enc_attributes); @@ -144,7 +138,6 @@ TEH_PG_select_aml_attributes ( "select_aml_attributes_inc", "SELECT" " kyc_attributes_serial_id" - ",provider" ",collection_time" ",encrypted_attributes" " FROM kyc_attributes" @@ -152,6 +145,17 @@ TEH_PG_select_aml_attributes ( " AND kyc_attributes_serial_id > $2" " ORDER BY kyc_attributes_serial_id ASC" " LIMIT $3"); + PREPARE (pg, + "select_aml_attributes_dec", + "SELECT" + " kyc_attributes_serial_id" + ",collection_time" + ",encrypted_attributes" + " FROM kyc_attributes" + " WHERE h_payto=$1" + " AND kyc_attributes_serial_id < $2" + " ORDER BY kyc_attributes_serial_id DESC" + " LIMIT $3"); qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, stmt, params, diff --git a/src/exchangedb/pg_select_deposit_amounts_for_kyc_check.c b/src/exchangedb/pg_select_deposit_amounts_for_kyc_check.c new file mode 100644 index 000000000..c34fd1da5 --- /dev/null +++ b/src/exchangedb/pg_select_deposit_amounts_for_kyc_check.c @@ -0,0 +1,153 @@ +/* + 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_select_deposit_amounts_for_kyc_check.c + * @brief Implementation of the select_deposit_amounts_for_kyc_check function for Postgres + * @author Christian Grothoff + */ +#include "platform.h" +#include "taler_error_codes.h" +#include "taler_dbevents.h" +#include "taler_pq_lib.h" +#include "pg_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 PostgresClosure *pg; + + /** + * 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 (void *cls, + PGresult *result, + unsigned int num_results) +{ + struct KycAmountCheckContext *ctx = cls; + struct PostgresClosure *pg = ctx->pg; + + 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 +TEH_PG_select_deposit_amounts_for_kyc_check ( + void *cls, + const struct TALER_PaytoHashP *h_payto, + struct GNUNET_TIME_Absolute time_limit, + TALER_EXCHANGEDB_KycAmountCallback kac, + void *kac_cls) +{ + struct PostgresClosure *pg = 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, + .pg = pg, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (pg, + "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=$1" + " AND bd.exchange_timestamp >= $2" + " ORDER BY bd.exchange_timestamp DESC"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->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/pg_select_deposit_amounts_for_kyc_check.h b/src/exchangedb/pg_select_deposit_amounts_for_kyc_check.h new file mode 100644 index 000000000..7e4ab31b2 --- /dev/null +++ b/src/exchangedb/pg_select_deposit_amounts_for_kyc_check.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/> + */ +/** + * @file exchangedb/pg_select_deposit_amounts_for_kyc_check.h + * @brief implementation of the select_deposit_amounts_for_kyc_check function for Postgres + * @author Christian Grothoff + */ +#ifndef PG_SELECT_DEPOSIT_AMOUNTS_FOR_KYC_CHECK_H +#define PG_SELECT_DEPOSIT_AMOUNTS_FOR_KYC_CHECK_H + +#include "taler_util.h" +#include "taler_json_lib.h" +#include "taler_exchangedb_plugin.h" + + +/** + * 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 +TEH_PG_select_deposit_amounts_for_kyc_check ( + void *cls, + const struct TALER_PaytoHashP *h_payto, + struct GNUNET_TIME_Absolute time_limit, + TALER_EXCHANGEDB_KycAmountCallback kac, + void *kac_cls); + + +#endif diff --git a/src/exchangedb/pg_select_merge_amounts_for_kyc_check.c b/src/exchangedb/pg_select_merge_amounts_for_kyc_check.c index 417d78ec7..8df91a398 100644 --- a/src/exchangedb/pg_select_merge_amounts_for_kyc_check.c +++ b/src/exchangedb/pg_select_merge_amounts_for_kyc_check.c @@ -131,7 +131,6 @@ TEH_PG_select_merge_amounts_for_kyc_check ( }; enum GNUNET_DB_QueryStatus qs; - PREPARE (pg, "select_kyc_relevant_merge_events", "SELECT" diff --git a/src/exchangedb/pg_select_purse_decisions_above_serial_id.c b/src/exchangedb/pg_select_purse_decisions_above_serial_id.c index f301ea78a..4d94cb039 100644 --- a/src/exchangedb/pg_select_purse_decisions_above_serial_id.c +++ b/src/exchangedb/pg_select_purse_decisions_above_serial_id.c @@ -85,7 +85,7 @@ purse_decision_serial_helper_cb (void *cls, &no_reserve), TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", &val), - GNUNET_PQ_result_spec_uint64 ("purse_deposit_serial_id", + GNUNET_PQ_result_spec_uint64 ("purse_decision_serial_id", &rowid), GNUNET_PQ_result_spec_end }; diff --git a/src/exchangedb/pg_select_purse_deposits_above_serial_id.c b/src/exchangedb/pg_select_purse_deposits_above_serial_id.c index bb4320663..4c5f0f19e 100644 --- a/src/exchangedb/pg_select_purse_deposits_above_serial_id.c +++ b/src/exchangedb/pg_select_purse_deposits_above_serial_id.c @@ -88,7 +88,7 @@ purse_deposit_serial_helper_cb (void *cls, &purse_balance), TALER_PQ_RESULT_SPEC_AMOUNT ("total", &purse_total), - TALER_PQ_RESULT_SPEC_AMOUNT ("deposit_fee", + TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit", &deposit.deposit_fee), GNUNET_PQ_result_spec_allow_null ( GNUNET_PQ_result_spec_string ("partner_base_url", @@ -176,6 +176,7 @@ TEH_PG_select_purse_deposits_above_serial_id ( ",pd.coin_sig" ",partner_base_url" ",denom.denom_pub" + ",denom.fee_deposit" ",pm.reserve_pub" ",kc.coin_pub" ",kc.age_commitment_hash" diff --git a/src/exchangedb/pg_select_purse_requests_above_serial_id.c b/src/exchangedb/pg_select_purse_requests_above_serial_id.c index 61a4f2041..f4cb5219e 100644 --- a/src/exchangedb/pg_select_purse_requests_above_serial_id.c +++ b/src/exchangedb/pg_select_purse_requests_above_serial_id.c @@ -98,7 +98,7 @@ purse_requests_serial_helper_cb (void *cls, &purse_sig), GNUNET_PQ_result_spec_auto_from_type ("merge_pub", &merge_pub), - GNUNET_PQ_result_spec_uint64 ("purse_requests_request_serial_id", + GNUNET_PQ_result_spec_uint64 ("purse_requests_serial_id", &rowid), GNUNET_PQ_result_spec_end }; diff --git a/src/exchangedb/pg_select_reserve_closed_above_serial_id.c b/src/exchangedb/pg_select_reserve_closed_above_serial_id.c index d24d6a600..7efba3c2a 100644 --- a/src/exchangedb/pg_select_reserve_closed_above_serial_id.c +++ b/src/exchangedb/pg_select_reserve_closed_above_serial_id.c @@ -22,7 +22,7 @@ #include "taler_error_codes.h" #include "taler_dbevents.h" #include "taler_pq_lib.h" -#include "pg_get_reserve_history.h" +#include "pg_select_reserve_closed_above_serial_id.h" #include "plugin_exchangedb_common.h" #include "pg_helper.h" @@ -146,8 +146,6 @@ TEH_PG_select_reserve_closed_above_serial_id ( }; enum GNUNET_DB_QueryStatus qs; - /* Used in #postgres_select_reserve_closed_above_serial_id() to - obtain information about closed reserves */ PREPARE ( pg, "reserves_close_get_incr", diff --git a/src/exchangedb/pg_trigger_kyc_rule_for_account.c b/src/exchangedb/pg_trigger_kyc_rule_for_account.c index 7220419cf..e6f5ffcf9 100644 --- a/src/exchangedb/pg_trigger_kyc_rule_for_account.c +++ b/src/exchangedb/pg_trigger_kyc_rule_for_account.c @@ -31,45 +31,66 @@ TEH_PG_trigger_kyc_rule_for_account ( void *cls, const char *payto_uri, const struct TALER_PaytoHashP *h_payto, - const union TALER_AccountPublicKeyP *account_pub, + 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) + uint64_t *requirement_row, + bool *bad_kyc_auth) { struct PostgresClosure *pg = cls; 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 GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (h_payto), - NULL == account_pub + 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 (account_pub), + : GNUNET_PQ_query_param_auto_from_type (check_merchant_pub), NULL == payto_uri ? GNUNET_PQ_query_param_null () : GNUNET_PQ_query_param_string (payto_uri), 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 (pg, "trigger_kyc_rule_for_account", "SELECT" " out_legitimization_measure_serial_id" - " AS 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);"); + "($1, $2, $3, $4, $5, $6, $7, $8);"); - return GNUNET_PQ_eval_prepared_singleton_select ( + qs = GNUNET_PQ_eval_prepared_singleton_select ( pg->conn, "trigger_kyc_rule_for_account", params, rs); + GNUNET_free (notify_str); + return qs; } diff --git a/src/exchangedb/pg_trigger_kyc_rule_for_account.h b/src/exchangedb/pg_trigger_kyc_rule_for_account.h index 7c8db0445..56ee0ca8b 100644 --- a/src/exchangedb/pg_trigger_kyc_rule_for_account.h +++ b/src/exchangedb/pg_trigger_kyc_rule_for_account.h @@ -34,11 +34,16 @@ * can be NULL if @a h_payto is already * guaranteed to be in wire_targets * @param h_payto hash of @a payto_uri - * @param account_pub public key to enable for the + * @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 @@ -46,9 +51,11 @@ TEH_PG_trigger_kyc_rule_for_account ( void *cls, const char *payto_uri, const struct TALER_PaytoHashP *h_payto, - const union TALER_AccountPublicKeyP *account_pub, + 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); + uint64_t *requirement_row, + bool *bad_kyc_auth); #endif diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index dee515a0c..b5d410fc1 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -38,9 +38,11 @@ #include "pg_delete_aggregation_transient.h" #include "pg_get_link_data.h" #include "pg_helper.h" +#include "pg_do_check_deposit_idempotent.h" #include "pg_do_reserve_open.h" #include "pg_get_coin_transactions.h" #include "pg_get_expired_reserves.h" +#include "pg_lookup_rules_by_access_token.h" #include "pg_lookup_h_payto_by_access_token.h" #include "pg_get_purse_request.h" #include "pg_get_reserve_history.h" @@ -55,7 +57,9 @@ #include "pg_lookup_records_by_table.h" #include "pg_lookup_kyc_status_by_token.h" #include "pg_lookup_serial_by_table.h" +#include "pg_select_deposit_amounts_for_kyc_check.h" #include "pg_lookup_pending_legitimization.h" +#include "pg_lookup_completed_legitimization.h" #include "pg_lookup_active_legitimization.h" #include "pg_select_account_merges_above_serial_id.h" #include "pg_select_all_purse_decisions_above_serial_id.h" @@ -79,11 +83,11 @@ #include "pg_get_kyc_rules.h" #include "pg_select_aggregation_amounts_for_kyc_check.h" #include "pg_kyc_provider_account_lookup.h" -#include "pg_insert_kyc_requirement_for_account.h" #include "pg_lookup_kyc_process_by_account.h" #include "pg_update_kyc_process_by_row.h" #include "pg_insert_kyc_requirement_process.h" #include "pg_select_withdraw_amounts_for_kyc_check.h" +#include "pg_insert_active_legitimization_measure.h" #include "pg_select_merge_amounts_for_kyc_check.h" #include "pg_profit_drains_set_finished.h" #include "pg_profit_drains_get_pending.h" @@ -225,13 +229,10 @@ #include "pg_test_aml_officer.h" #include "pg_lookup_aml_officer.h" #include "pg_trigger_aml_process.h" -// #include "pg_select_justification_for_missing_wire.h" #include "pg_lookup_kyc_requirement_by_row.h" -// #include "pg_select_aml_history.h" -// #include "pg_select_aml_process.h" -// #include "pg_select_aml_threshold.h" #include "pg_insert_aml_decision.h" #include "pg_batch_ensure_coin_known.h" +#include "plugin_exchangedb_postgres.h" /** * Set to 1 to enable Postgres auto_explain module. This will @@ -328,6 +329,10 @@ TEH_PG_internal_setup (struct PostgresClosure *pg) * 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) { const struct GNUNET_CONFIGURATION_Handle *cfg = cls; @@ -504,7 +509,6 @@ libtaler_plugin_exchangedb_postgres_init (void *cls) = &TEH_PG_get_kyc_rules; plugin->kyc_provider_account_lookup = &TEH_PG_kyc_provider_account_lookup; - // FIXME: plugin->insert_kyc_requirement_for_account = &TEH_PG_insert_kyc_requirement_for_account; plugin->lookup_kyc_process_by_account = &TEH_PG_lookup_kyc_process_by_account; plugin->update_kyc_process_by_row @@ -583,6 +587,8 @@ libtaler_plugin_exchangedb_postgres_init (void *cls) = &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 @@ -745,6 +751,10 @@ libtaler_plugin_exchangedb_postgres_init (void *cls) = &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 @@ -755,6 +765,8 @@ libtaler_plugin_exchangedb_postgres_init (void *cls) = &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 @@ -805,6 +817,8 @@ libtaler_plugin_exchangedb_postgres_init (void *cls) = &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->trigger_aml_process = &TEH_PG_trigger_aml_process; plugin->insert_aml_decision @@ -831,6 +845,10 @@ libtaler_plugin_exchangedb_postgres_init (void *cls) * @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) { struct TALER_EXCHANGEDB_Plugin *plugin = cls; diff --git a/src/exchangedb/plugin_exchangedb_postgres.h b/src/exchangedb/plugin_exchangedb_postgres.h new file mode 100644 index 000000000..daceee7c7 --- /dev/null +++ b/src/exchangedb/plugin_exchangedb_postgres.h @@ -0,0 +1,43 @@ +/* + This file is part of TALER + Copyright (C) 2014--2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +/** + * @file plugin_exchangedb_postgres.h + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Florian Dold + * @author Christian Grothoff + * @author Sree Harsha Totakura + * @author Marcello Stanisci + * @author Özgür Kesim + */ +#ifndef PLUGIN_EXCHANGEDB_POSTGRES_H +#define PLUGIN_EXCHANGEDB_POSTGRES_H +#include "platform.h" +#include "taler_error_codes.h" +#include "taler_dbevents.h" +#include "taler_pq_lib.h" + + +/** + * Connect to the database if the connection does not exist yet. + * + * @param pg the plugin-specific state + * @return #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +TEH_PG_internal_setup (struct PostgresClosure *pg); + +#endif diff --git a/src/exchangedb/procedures.sql.in b/src/exchangedb/procedures.sql.in index 99b932951..0c25e8f5d 100644 --- a/src/exchangedb/procedures.sql.in +++ b/src/exchangedb/procedures.sql.in @@ -27,6 +27,7 @@ SET search_path TO exchange; #include "exchange_do_batch_withdraw_insert.sql" #include "exchange_do_age_withdraw.sql" #include "exchange_do_deposit.sql" +#include "exchange_do_check_deposit_idempotent.sql" #include "exchange_do_melt.sql" #include "exchange_do_select_deposits_missing_wire.sql" #include "exchange_do_select_justification_for_missing_wire.sql" @@ -53,5 +54,7 @@ SET search_path TO exchange; #include "exchange_do_trigger_kyc_rule_for_account.sql" #include "exchange_do_lookup_kyc_requirement_by_row.sql" #include "exchange_do_insert_programmatic_legitimization_outcome.sql" +#include "exchange_do_insert_active_legitimization_measure.sql" +#include "exchange_do_select_aggregations_above_serial.sql" COMMIT; diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c index cb78d0544..93eed3e52 100644 --- a/src/exchangedb/test_exchangedb.c +++ b/src/exchangedb/test_exchangedb.c @@ -340,9 +340,8 @@ create_denom_key_pair (unsigned int size, static struct TALER_Amount value; -static struct TALER_DenomFeeSet fees; +static struct TALER_DenomFeeSet global_fees; static struct TALER_Amount fee_closing; -static struct TALER_Amount amount_with_fee; /** @@ -600,7 +599,7 @@ cb_wt_check (void *cls, /** * Here we store the hash of the payto URI. */ -static struct TALER_PaytoHashP wire_target_h_payto; +static struct TALER_PaytoHashP global_wire_target_h_payto; /** @@ -769,7 +768,7 @@ test_gc (void) dkp = create_denom_key_pair (RSA_KEY_SIZE, past, &value, - &fees); + &global_fees); GNUNET_assert (NULL != dkp); if (GNUNET_OK != plugin->gc (plugin->cls)) @@ -964,7 +963,7 @@ test_wire_out (const struct TALER_EXCHANGEDB_BatchDeposit *bd) coin_pub_wt = deposit->coin.coin_pub; coin_value_wt = deposit->amount_with_fee; - coin_fee_wt = fees.deposit; + coin_fee_wt = global_fees.deposit; GNUNET_assert (0 < TALER_amount_subtract (&transfer_value_wt, &coin_value_wt, @@ -984,6 +983,7 @@ test_wire_out (const struct TALER_EXCHANGEDB_BatchDeposit *bd) struct TALER_Amount coin_fee2; struct GNUNET_TIME_Timestamp execution_time2; struct TALER_EXCHANGEDB_KycStatus kyc; + union TALER_AccountPublicKeyP account_pub; h_contract_terms_wt2.hash.bits[0]++; FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != @@ -997,7 +997,8 @@ test_wire_out (const struct TALER_EXCHANGEDB_BatchDeposit *bd) &execution_time2, &coin_contribution2, &coin_fee2, - &kyc)); + &kyc, + &account_pub)); } { struct TALER_ReservePublicKeyP rpub; @@ -1029,6 +1030,7 @@ test_wire_out (const struct TALER_EXCHANGEDB_BatchDeposit *bd) struct TALER_Amount coin_fee2; struct GNUNET_TIME_Timestamp execution_time2; struct TALER_EXCHANGEDB_KycStatus kyc; + union TALER_AccountPublicKeyP account_pub; FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->lookup_transfer_by_deposit (plugin->cls, @@ -1041,7 +1043,8 @@ test_wire_out (const struct TALER_EXCHANGEDB_BatchDeposit *bd) &execution_time2, &coin_contribution2, &coin_fee2, - &kyc)); + &kyc, + &account_pub)); GNUNET_assert (0 == GNUNET_memcmp (&wtid2, &wire_out_wtid)); GNUNET_assert (GNUNET_TIME_timestamp_cmp (execution_time2, @@ -1190,13 +1193,10 @@ run (void *cls) struct TALER_CoinSpendPublicKeyP cpub2; struct TALER_MerchantPublicKeyP mpub2; struct TALER_EXCHANGEDB_Refund refund; - struct TALER_EXCHANGEDB_TransactionList *tl; - struct TALER_EXCHANGEDB_TransactionList *tlp; const char *sndr = "payto://x-taler-bank/localhost:8080/1"; const char *rcvr = "payto://x-taler-bank/localhost:8080/2"; const uint32_t num_partitions = 10; unsigned int matched; - unsigned int cnt; enum GNUNET_DB_QueryStatus qs; struct GNUNET_TIME_Timestamp now; struct TALER_WireSaltP salt; @@ -1209,6 +1209,7 @@ run (void *cls) uint64_t melt_serial_id; struct TALER_PlanchetMasterSecretP ps; union GNUNET_CRYPTO_BlindingSecretP bks; + struct TALER_Amount amount_with_fee; const struct TALER_ExchangeWithdrawValues *alg_values = TALER_denom_ewv_rsa_singleton (); @@ -1265,16 +1266,16 @@ run (void *cls) &value)); GNUNET_assert (GNUNET_OK == TALER_string_to_amount (CURRENCY ":0.000010", - &fees.withdraw)); + &global_fees.withdraw)); GNUNET_assert (GNUNET_OK == TALER_string_to_amount (CURRENCY ":0.000010", - &fees.deposit)); + &global_fees.deposit)); GNUNET_assert (GNUNET_OK == TALER_string_to_amount (CURRENCY ":0.000010", - &fees.refresh)); + &global_fees.refresh)); GNUNET_assert (GNUNET_OK == TALER_string_to_amount (CURRENCY ":0.000010", - &fees.refund)); + &global_fees.refund)); GNUNET_assert (GNUNET_OK == TALER_string_to_amount (CURRENCY ":1.000010", &amount_with_fee)); @@ -1345,7 +1346,7 @@ run (void *cls) dkp = create_denom_key_pair (RSA_KEY_SIZE, now, &value, - &fees); + &global_fees); GNUNET_assert (NULL != dkp); TALER_denom_pub_hash (&dkp->pub, &cbc.denom_pub_hash); @@ -1548,12 +1549,12 @@ run (void *cls) refund.details.h_contract_terms = bd.h_contract_terms; refund.details.rtransaction_id = 1; refund.details.refund_amount = value; - refund.details.refund_fee = fees.refund; + refund.details.refund_fee = global_fees.refund; RND_BLK (&refund.details.merchant_sig); FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->do_refund (plugin->cls, &refund, - &fees.deposit, + &global_fees.deposit, known_coin_id, ¬_found, &refund_ok, @@ -1609,7 +1610,7 @@ run (void *cls) TALER_amount_cmp (&refresh.amount_with_fee, &ret_refresh_session.session.amount_with_fee)); FAILIF (0 != - TALER_amount_cmp (&fees.refresh, + TALER_amount_cmp (&global_fees.refresh, &ret_refresh_session.melt_fee)); FAILIF (0 != GNUNET_memcmp (&refresh.rc, @@ -1636,6 +1637,7 @@ run (void *cls) } /* do refresh-reveal */ + now = GNUNET_TIME_timestamp_get (); { new_dkp = GNUNET_new_array (MELT_NEW_COINS, struct DenomKeyPair *); @@ -1647,16 +1649,14 @@ run (void *cls) for (unsigned int cnt = 0; cnt < MELT_NEW_COINS; cnt++) { struct TALER_EXCHANGEDB_RefreshRevealedCoin *ccoin; - struct GNUNET_TIME_Timestamp now; struct GNUNET_CRYPTO_BlindedMessage *rp; struct GNUNET_CRYPTO_RsaBlindedMessage *rsa; struct TALER_BlindedPlanchet *bp; - now = GNUNET_TIME_timestamp_get (); new_dkp[cnt] = create_denom_key_pair (RSA_KEY_SIZE, now, &value, - &fees); + &global_fees); GNUNET_assert (NULL != new_dkp[cnt]); new_denom_pubs[cnt] = new_dkp[cnt]->pub; ccoin = &revealed_coins[cnt]; @@ -1733,12 +1733,12 @@ run (void *cls) { /* Just to test fetching a coin with melt history */ struct TALER_EXCHANGEDB_TransactionList *tl; - enum GNUNET_DB_QueryStatus qs; uint64_t etag; struct TALER_Amount balance; struct TALER_DenominationHashP h_denom_pub; qs = plugin->get_coin_transactions (plugin->cls, + true, &refresh.coin.coin_pub, 0, 0, @@ -1893,89 +1893,95 @@ run (void *cls) FAILIF (0 > qs); FAILIF (NULL == rh); rh_head = rh; - for (cnt = 0; NULL != rh_head; rh_head = rh_head->next, cnt++) { - switch (rh_head->type) + unsigned int cnt; + + for (cnt = 0; + NULL != rh_head; + rh_head = rh_head->next, cnt++) { - case TALER_EXCHANGEDB_RO_BANK_TO_EXCHANGE: - bt = rh_head->details.bank; - FAILIF (0 != - GNUNET_memcmp (&bt->reserve_pub, - &reserve_pub)); - /* this is the amount we transferred twice*/ - FAILIF (1 != bt->amount.value); - FAILIF (1000 != bt->amount.fraction); - FAILIF (0 != strcmp (CURRENCY, bt->amount.currency)); - FAILIF (NULL == bt->sender_account_details); - break; - case TALER_EXCHANGEDB_RO_WITHDRAW_COIN: - withdraw = rh_head->details.withdraw; - FAILIF (0 != - GNUNET_memcmp (&withdraw->reserve_pub, - &reserve_pub)); - FAILIF (0 != - GNUNET_memcmp (&withdraw->h_coin_envelope, - &cbc.h_coin_envelope)); - break; - case TALER_EXCHANGEDB_RO_RECOUP_COIN: + switch (rh_head->type) { - struct TALER_EXCHANGEDB_Recoup *recoup = rh_head->details.recoup; - + case TALER_EXCHANGEDB_RO_BANK_TO_EXCHANGE: + bt = rh_head->details.bank; FAILIF (0 != - GNUNET_memcmp (&recoup->coin_sig, - &coin_sig)); - FAILIF (0 != - GNUNET_memcmp (&recoup->coin_blind, - &coin_blind)); - FAILIF (0 != - GNUNET_memcmp (&recoup->reserve_pub, + GNUNET_memcmp (&bt->reserve_pub, &reserve_pub)); + /* this is the amount we transferred twice*/ + FAILIF (1 != bt->amount.value); + FAILIF (1000 != bt->amount.fraction); + FAILIF (0 != strcmp (CURRENCY, bt->amount.currency)); + FAILIF (NULL == bt->sender_account_details); + break; + case TALER_EXCHANGEDB_RO_WITHDRAW_COIN: + withdraw = rh_head->details.withdraw; FAILIF (0 != - GNUNET_memcmp (&recoup->coin.coin_pub, - &deposit.coin.coin_pub)); - FAILIF (0 != - TALER_amount_cmp (&recoup->value, - &value)); - } - break; - case TALER_EXCHANGEDB_RO_EXCHANGE_TO_BANK: - { - struct TALER_EXCHANGEDB_ClosingTransfer *closing - = rh_head->details.closing; - - FAILIF (0 != - GNUNET_memcmp (&closing->reserve_pub, + GNUNET_memcmp (&withdraw->reserve_pub, &reserve_pub)); - FAILIF (0 != TALER_amount_cmp (&closing->amount, - &amount_with_fee)); - FAILIF (0 != TALER_amount_cmp (&closing->closing_fee, - &fee_closing)); - } - break; - case TALER_EXCHANGEDB_RO_PURSE_MERGE: - { - /* FIXME: not yet tested */ - break; - } - case TALER_EXCHANGEDB_RO_HISTORY_REQUEST: - { - /* FIXME: not yet tested */ + FAILIF (0 != + GNUNET_memcmp (&withdraw->h_coin_envelope, + &cbc.h_coin_envelope)); break; - } - case TALER_EXCHANGEDB_RO_OPEN_REQUEST: - { - /* FIXME: not yet tested */ + case TALER_EXCHANGEDB_RO_RECOUP_COIN: + { + struct TALER_EXCHANGEDB_Recoup *recoup = rh_head->details.recoup; + + FAILIF (0 != + GNUNET_memcmp (&recoup->coin_sig, + &coin_sig)); + FAILIF (0 != + GNUNET_memcmp (&recoup->coin_blind, + &coin_blind)); + FAILIF (0 != + GNUNET_memcmp (&recoup->reserve_pub, + &reserve_pub)); + FAILIF (0 != + GNUNET_memcmp (&recoup->coin.coin_pub, + &deposit.coin.coin_pub)); + FAILIF (0 != + TALER_amount_cmp (&recoup->value, + &value)); + } break; - } - case TALER_EXCHANGEDB_RO_CLOSE_REQUEST: - { - /* FIXME: not yet tested */ + case TALER_EXCHANGEDB_RO_EXCHANGE_TO_BANK: + { + struct TALER_EXCHANGEDB_ClosingTransfer *closing + = rh_head->details.closing; + + FAILIF (0 != + GNUNET_memcmp (&closing->reserve_pub, + &reserve_pub)); + FAILIF (0 != TALER_amount_cmp (&closing->amount, + &amount_with_fee)); + FAILIF (0 != TALER_amount_cmp (&closing->closing_fee, + &fee_closing)); + } break; + case TALER_EXCHANGEDB_RO_PURSE_MERGE: + { + /* FIXME: not yet tested */ + break; + } + case TALER_EXCHANGEDB_RO_HISTORY_REQUEST: + { + /* FIXME: not yet tested */ + break; + } + case TALER_EXCHANGEDB_RO_OPEN_REQUEST: + { + /* FIXME: not yet tested */ + break; + } + case TALER_EXCHANGEDB_RO_CLOSE_REQUEST: + { + /* FIXME: not yet tested */ + break; + } } } + GNUNET_assert (4 == cnt); + FAILIF (4 != cnt); } - GNUNET_assert (4 == cnt); - FAILIF (4 != cnt); auditor_row_cnt = 0; FAILIF (0 >= @@ -2002,8 +2008,10 @@ run (void *cls) uint64_t etag = 0; struct TALER_Amount balance; struct TALER_DenominationHashP h_denom_pub; + struct TALER_EXCHANGEDB_TransactionList *tl; qs = plugin->get_coin_transactions (plugin->cls, + true, &refund.coin.coin_pub, 0, 0, @@ -2011,108 +2019,109 @@ run (void *cls) &balance, &h_denom_pub, &tl); - } - FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs); - GNUNET_assert (NULL != tl); - matched = 0; - for (tlp = tl; NULL != tlp; tlp = tlp->next) - { - switch (tlp->type) + FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs); + GNUNET_assert (NULL != tl); + matched = 0; + for (struct TALER_EXCHANGEDB_TransactionList *tlp = tl; + NULL != tlp; + tlp = tlp->next) { - case TALER_EXCHANGEDB_TT_DEPOSIT: + switch (tlp->type) { - struct TALER_EXCHANGEDB_DepositListEntry *have = tlp->details.deposit; - - /* Note: we're not comparing the denomination keys, as there is - still the question of whether we should even bother exporting - them here. */ + case TALER_EXCHANGEDB_TT_DEPOSIT: + { + struct TALER_EXCHANGEDB_DepositListEntry *have = tlp->details.deposit; + + /* Note: we're not comparing the denomination keys, as there is + still the question of whether we should even bother exporting + them here. */ + FAILIF (0 != + GNUNET_memcmp (&have->csig, + &deposit.csig)); + FAILIF (0 != + GNUNET_memcmp (&have->merchant_pub, + &bd.merchant_pub)); + FAILIF (0 != + GNUNET_memcmp (&have->h_contract_terms, + &bd.h_contract_terms)); + FAILIF (0 != + GNUNET_memcmp (&have->wire_salt, + &bd.wire_salt)); + FAILIF (GNUNET_TIME_timestamp_cmp (have->timestamp, + !=, + bd.wallet_timestamp)); + FAILIF (GNUNET_TIME_timestamp_cmp (have->refund_deadline, + !=, + bd.refund_deadline)); + FAILIF (GNUNET_TIME_timestamp_cmp (have->wire_deadline, + !=, + bd.wire_deadline)); + FAILIF (0 != TALER_amount_cmp (&have->amount_with_fee, + &deposit.amount_with_fee)); + matched |= 1; + break; + } + /* this coin pub was actually never melted... */ + case TALER_EXCHANGEDB_TT_MELT: FAILIF (0 != - GNUNET_memcmp (&have->csig, - &deposit.csig)); - FAILIF (0 != - GNUNET_memcmp (&have->merchant_pub, - &bd.merchant_pub)); - FAILIF (0 != - GNUNET_memcmp (&have->h_contract_terms, - &bd.h_contract_terms)); - FAILIF (0 != - GNUNET_memcmp (&have->wire_salt, - &bd.wire_salt)); - FAILIF (GNUNET_TIME_timestamp_cmp (have->timestamp, - !=, - bd.wallet_timestamp)); - FAILIF (GNUNET_TIME_timestamp_cmp (have->refund_deadline, - !=, - bd.refund_deadline)); - FAILIF (GNUNET_TIME_timestamp_cmp (have->wire_deadline, - !=, - bd.wire_deadline)); - FAILIF (0 != TALER_amount_cmp (&have->amount_with_fee, - &deposit.amount_with_fee)); - matched |= 1; + GNUNET_memcmp (&refresh.rc, + &tlp->details.melt->rc)); + matched |= 2; break; - } - /* this coin pub was actually never melted... */ - case TALER_EXCHANGEDB_TT_MELT: - FAILIF (0 != - GNUNET_memcmp (&refresh.rc, - &tlp->details.melt->rc)); - matched |= 2; - break; - case TALER_EXCHANGEDB_TT_REFUND: - { - struct TALER_EXCHANGEDB_RefundListEntry *have = tlp->details.refund; - - /* Note: we're not comparing the denomination keys, as there is - still the question of whether we should even bother exporting - them here. */ - FAILIF (0 != GNUNET_memcmp (&have->merchant_pub, - &refund.details.merchant_pub)); - FAILIF (0 != GNUNET_memcmp (&have->merchant_sig, - &refund.details.merchant_sig)); - FAILIF (0 != GNUNET_memcmp (&have->h_contract_terms, - &refund.details.h_contract_terms)); - FAILIF (have->rtransaction_id != refund.details.rtransaction_id); - FAILIF (0 != TALER_amount_cmp (&have->refund_amount, - &refund.details.refund_amount)); - FAILIF (0 != TALER_amount_cmp (&have->refund_fee, - &refund.details.refund_fee)); - matched |= 4; + case TALER_EXCHANGEDB_TT_REFUND: + { + struct TALER_EXCHANGEDB_RefundListEntry *have = tlp->details.refund; + + /* Note: we're not comparing the denomination keys, as there is + still the question of whether we should even bother exporting + them here. */ + FAILIF (0 != GNUNET_memcmp (&have->merchant_pub, + &refund.details.merchant_pub)); + FAILIF (0 != GNUNET_memcmp (&have->merchant_sig, + &refund.details.merchant_sig)); + FAILIF (0 != GNUNET_memcmp (&have->h_contract_terms, + &refund.details.h_contract_terms)); + FAILIF (have->rtransaction_id != refund.details.rtransaction_id); + FAILIF (0 != TALER_amount_cmp (&have->refund_amount, + &refund.details.refund_amount)); + FAILIF (0 != TALER_amount_cmp (&have->refund_fee, + &refund.details.refund_fee)); + matched |= 4; + break; + } + case TALER_EXCHANGEDB_TT_RECOUP: + { + struct TALER_EXCHANGEDB_RecoupListEntry *recoup = + tlp->details.recoup; + + FAILIF (0 != GNUNET_memcmp (&recoup->coin_sig, + &coin_sig)); + FAILIF (0 != GNUNET_memcmp (&recoup->coin_blind, + &coin_blind)); + FAILIF (0 != GNUNET_memcmp (&recoup->reserve_pub, + &reserve_pub)); + FAILIF (0 != TALER_amount_cmp (&recoup->value, + &value)); + matched |= 8; + break; + } + case TALER_EXCHANGEDB_TT_OLD_COIN_RECOUP: + /* TODO: check fields better... */ + matched |= 16; break; - } - case TALER_EXCHANGEDB_TT_RECOUP: - { - struct TALER_EXCHANGEDB_RecoupListEntry *recoup = - tlp->details.recoup; - - FAILIF (0 != GNUNET_memcmp (&recoup->coin_sig, - &coin_sig)); - FAILIF (0 != GNUNET_memcmp (&recoup->coin_blind, - &coin_blind)); - FAILIF (0 != GNUNET_memcmp (&recoup->reserve_pub, - &reserve_pub)); - FAILIF (0 != TALER_amount_cmp (&recoup->value, - &value)); - matched |= 8; + default: + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unexpected coin history transaction type: %d\n", + tlp->type); + FAILIF (1); break; } - case TALER_EXCHANGEDB_TT_OLD_COIN_RECOUP: - /* TODO: check fields better... */ - matched |= 16; - break; - default: - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected coin history transaction type: %d\n", - tlp->type); - FAILIF (1); - break; } - } - FAILIF (31 != matched); - - plugin->free_coin_transaction_list (plugin->cls, - tl); + FAILIF (31 != matched); + plugin->free_coin_transaction_list (plugin->cls, + tl); + } /* Tests for deposits+wire */ TALER_denom_sig_free (&deposit.coin.denom_sig); @@ -2147,19 +2156,19 @@ run (void *cls) plugin->start (plugin->cls, "test-3")); { - uint64_t known_coin_id; + uint64_t known_coin_id2; struct TALER_DenominationHashP dph; struct TALER_AgeCommitmentHash agh; FAILIF (TALER_EXCHANGEDB_CKS_ADDED != plugin->ensure_coin_known (plugin->cls, &deposit.coin, - &known_coin_id, + &known_coin_id2, &dph, &agh)); } + now = GNUNET_TIME_timestamp_get (); { - struct GNUNET_TIME_Timestamp now; struct GNUNET_TIME_Timestamp r; struct TALER_Amount deposit_fee; struct TALER_MerchantWireHashP h_wire; @@ -2167,7 +2176,6 @@ run (void *cls) uint32_t bad_idx; bool ctr_conflict; - now = GNUNET_TIME_timestamp_get (); TALER_payto_hash (bd.receiver_wire_account, &bd.wire_target_h_payto); FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != @@ -2226,7 +2234,7 @@ run (void *cls) FAILIF (0 != strcmp (payto_uri2, bd.receiver_wire_account)); TALER_payto_hash (payto_uri2, - &wire_target_h_payto); + &global_wire_target_h_payto); GNUNET_free (payto_uri2); } @@ -2239,7 +2247,7 @@ run (void *cls) sizeof (wtid)); FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->aggregate (plugin->cls, - &wire_target_h_payto, + &global_wire_target_h_payto, &bd.merchant_pub, &wtid, &total)); @@ -2262,27 +2270,30 @@ run (void *cls) TALER_string_to_amount (CURRENCY ":42", &total)); FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != - plugin->select_aggregation_transient (plugin->cls, - &wire_target_h_payto, - &bd.merchant_pub, - "x-bank", - &wtid2, - &total2)); + plugin->select_aggregation_transient ( + plugin->cls, + &global_wire_target_h_payto, + &bd.merchant_pub, + "x-bank", + &wtid2, + &total2)); FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != - plugin->create_aggregation_transient (plugin->cls, - &wire_target_h_payto, - "x-bank", - &bd.merchant_pub, - &wtid, - 0, - &total)); + plugin->create_aggregation_transient ( + plugin->cls, + &global_wire_target_h_payto, + "x-bank", + &bd.merchant_pub, + &wtid, + 0, + &total)); FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != - plugin->select_aggregation_transient (plugin->cls, - &wire_target_h_payto, - &bd.merchant_pub, - "x-bank", - &wtid2, - &total2)); + plugin->select_aggregation_transient ( + plugin->cls, + &global_wire_target_h_payto, + &bd.merchant_pub, + "x-bank", + &wtid2, + &total2)); FAILIF (0 != GNUNET_memcmp (&wtid2, &wtid)); @@ -2293,18 +2304,20 @@ run (void *cls) TALER_string_to_amount (CURRENCY ":43", &total)); FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != - plugin->update_aggregation_transient (plugin->cls, - &wire_target_h_payto, - &wtid, - 0, - &total)); + plugin->update_aggregation_transient ( + plugin->cls, + &global_wire_target_h_payto, + &wtid, + 0, + &total)); FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != - plugin->select_aggregation_transient (plugin->cls, - &wire_target_h_payto, - &bd.merchant_pub, - "x-bank", - &wtid2, - &total2)); + plugin->select_aggregation_transient ( + plugin->cls, + &global_wire_target_h_payto, + &bd.merchant_pub, + "x-bank", + &wtid2, + &total2)); FAILIF (0 != GNUNET_memcmp (&wtid2, &wtid)); @@ -2312,16 +2325,18 @@ run (void *cls) TALER_amount_cmp (&total2, &total)); FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != - plugin->delete_aggregation_transient (plugin->cls, - &wire_target_h_payto, - &wtid)); + plugin->delete_aggregation_transient ( + plugin->cls, + &global_wire_target_h_payto, + &wtid)); FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != - plugin->select_aggregation_transient (plugin->cls, - &wire_target_h_payto, - &bd.merchant_pub, - "x-bank", - &wtid2, - &total2)); + plugin->select_aggregation_transient ( + plugin->cls, + &global_wire_target_h_payto, + &bd.merchant_pub, + "x-bank", + &wtid2, + &total2)); } FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != plugin->commit (plugin->cls)); diff --git a/src/extensions/age_restriction/age_restriction.c b/src/extensions/age_restriction/age_restriction.c index 08b598d50..3d160e49c 100644 --- a/src/extensions/age_restriction/age_restriction.c +++ b/src/extensions/age_restriction/age_restriction.c @@ -164,6 +164,10 @@ struct TALER_Extension TE_age_restriction = { * @return pointer to TALER_Extension on success or NULL otherwise. */ void * +libtaler_extension_age_restriction_init (void *arg); + +/* Declaration used to squash compiler warning */ +void * libtaler_extension_age_restriction_init (void *arg) { const struct GNUNET_CONFIGURATION_Handle *cfg = arg; @@ -243,6 +247,10 @@ libtaler_extension_age_restriction_init (void *arg) * @return pointer to TALER_Extension on success or NULL otherwise. */ void * +libtaler_extension_age_restriction_done (void *arg); + +/* Declaration used to squash compiler warning */ +void * libtaler_extension_age_restriction_done (void *arg) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, diff --git a/src/extensions/extensions.c b/src/extensions/extensions.c index 999e9317a..f3222178b 100644 --- a/src/extensions/extensions.c +++ b/src/extensions/extensions.c @@ -362,11 +362,10 @@ TALER_extensions_load_manifests ( } -/* +/** * Policy related */ - -static char *fulfillment2str[] = { +static const char *fulfillment2str[] = { [TALER_PolicyFulfillmentInitial] = "<init>", [TALER_PolicyFulfillmentReady] = "Ready", [TALER_PolicyFulfillmentSuccess] = "Success", diff --git a/src/include/taler_amount_lib.h b/src/include/taler_amount_lib.h index 71af13932..d3711c58b 100644 --- a/src/include/taler_amount_lib.h +++ b/src/include/taler_amount_lib.h @@ -265,6 +265,20 @@ TALER_amount_max (struct TALER_Amount *ma, /** + * Compute minimum of two amounts. + * + * @param[out] mi set to minimum of @a a1 and @a a2 + * @param a1 first amount + * @param a2 second amount + * @return #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +TALER_amount_min (struct TALER_Amount *mi, + const struct TALER_Amount *a1, + const struct TALER_Amount *a2); + + +/** * Compare the value/fraction of two amounts. Does not compare the currency. * Comparing amounts of different currencies will cause the program to abort(). * If unsure, check with #TALER_amount_cmp_currency() first to be sure that diff --git a/src/include/taler_auditordb_lib.h b/src/include/taler_auditordb_lib.h index 552788719..882e37e11 100644 --- a/src/include/taler_auditordb_lib.h +++ b/src/include/taler_auditordb_lib.h @@ -24,19 +24,129 @@ #define TALER_AUDITORDB_LIB_H -enum TALER_AUDITORDB_SuppressableTables +enum TALER_AUDITORDB_DeletableSuppressableTables { /** * For auditor_amount_arithmetic_inconsistency table. */ TALER_AUDITORDB_AMOUNT_ARITHMETIC_INCONSISTENCY, + + /** + * For auditor_closure_lags table. + */ + TALER_AUDITORDB_CLOSURE_LAGS, + + /** + * For auditor_progress table. + */ + TALER_AUDITORDB_PROGRESS, + + /** + * For auditor_bad_sig_losses table. + */ + TALER_AUDITORDB_BAD_SIG_LOSSES, + + /** + * For auditor_coin_inconsistency table. + */ + TALER_AUDITORDB_COIN_INCONSISTENCY, + + /** + * For auditor_denomination_key_validity_withdraw_inconsistency table. + */ + TALER_AUDITORDB_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY, + + /** + * For auditor_denomination_pending table. + */ + TALER_AUDITORDB_DENOMINATION_PENDING, + + /** + * For auditor_denominations_without_sig table. + */ + TALER_AUDITORDB_DENOMINATIONS_WITHOUT_SIG, + + /** + * For auditor_deposit_confirmation table. + */ + TALER_AUDITORDB_DEPOSIT_CONFIRMATION, + + /** + * For auditor_emergency table. + */ + TALER_AUDITORDB_EMERGENCY, + + /** + * For auditor_emergency_by_count table. + */ + TALER_AUDITORDB_EMERGENCY_BY_COUNT, + + /** + * For auditor_fee_time_inconsistency table. + */ + TALER_AUDITORDB_FEE_TIME_INCONSISTENCY, + + /** + * For auditor_misattribution_in_inconsistency table. + */ + TALER_AUDITORDB_MISATTRIBUTION_IN_INCONSISTENCY, + + /** + * For auditor_purse_not_closed_inconsistency table. + */ + TALER_AUDITORDB_PURSE_NOT_CLOSED_INCONSISTENCY, + + /** + * For auditor_refreshes_hanging table. + */ + TALER_AUDITORDB_REFRESHES_HANGING, + + /** + * For auditor_reserve_balance_insufficient_inconsistency table. + */ + TALER_AUDITORDB_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY, + + /** + * For auditor_reserve_balance_summary_wrong_inconsistency table. + */ + TALER_AUDITORDB_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY, + + /** + * For auditor_reserve_in_inconsistency table. + */ + TALER_AUDITORDB_RESERVE_IN_INCONSISTENCY, + + /** + * For auditor_reserve_not_closed_inconsistency table. + */ + TALER_AUDITORDB_RESERVE_NOT_CLOSED_INCONSISTENCY, + + /** + * For auditor_row_inconsistency table. + */ + TALER_AUDITORDB_ROW_INCONSISTENCY, + + /** + * For auditor_row_minor_inconsistency table. + */ + TALER_AUDITORDB_ROW_MINOR_INCONSISTENCY, + + /** + * For auditor_wire_format_inconsistency table. + */ + TALER_AUDITORDB_WIRE_FORMAT_INCONSISTENCY, + + /** + * For auditor_wire_out_inconsistency table. + */ + TALER_AUDITORDB_WIRE_OUT_INCONSISTENCY, + /** * Terminal. */ - TALER_AUDITORDB_SUPPRESSABLE_TABLES_MAX + TALER_AUDITORDB_DELETABLESUPPRESSABLE_TABLES_MAX }; - /** * Initialize the plugin. * diff --git a/src/include/taler_auditordb_plugin.h b/src/include/taler_auditordb_plugin.h index 3a5ef2210..88241e25a 100644 --- a/src/include/taler_auditordb_plugin.h +++ b/src/include/taler_auditordb_plugin.h @@ -34,6 +34,7 @@ * 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 @@ -159,11 +160,6 @@ struct TALER_AUDITORDB_DepositConfirmation struct TALER_Amount total_without_fee; /** - * Length of the @e coin_pubs and @e coin_sigs arrays. - */ - unsigned int num_coins; - - /** * Array of the coin public keys involved in the * batch deposit operation. */ @@ -196,6 +192,18 @@ struct TALER_AUDITORDB_DepositConfirmation */ 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 @@ -215,12 +223,13 @@ struct TALER_AUDITORDB_Generic_Update */ struct TALER_AUDITORDB_AmountArithmeticInconsistency { - // FIXME: which row? 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; }; /** @@ -253,9 +262,11 @@ struct TALER_AUDITORDB_RowInconsistency 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; }; /** @@ -264,11 +275,12 @@ struct TALER_AUDITORDB_BadSigLosses 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; char *account; - + bool suppressed; }; /** @@ -283,6 +295,7 @@ struct TALER_AUDITORDB_Emergency struct GNUNET_TIME_Absolute deposit_start; struct GNUNET_TIME_Absolute deposit_end; struct TALER_Amount value; + bool suppressed; }; /** @@ -298,14 +311,14 @@ struct TALER_AUDITORDB_EmergenciesByCount struct GNUNET_TIME_Absolute start; struct GNUNET_TIME_Absolute deposit_end; struct TALER_Amount value; + bool suppressed; }; /** - * Information about a refreshes hanging + * Information about progress of the audit. */ struct TALER_AUDITORDB_Progress { - uint64_t row_id; char *progress_key; uint64_t progress_offset; }; @@ -316,8 +329,8 @@ struct TALER_AUDITORDB_Progress struct TALER_AUDITORDB_RefreshesHanging { uint64_t row_id; + uint64_t problem_row_id; struct TALER_Amount amount; - struct GNUNET_CRYPTO_EddsaPublicKey coin_pub; }; /** @@ -326,6 +339,7 @@ struct TALER_AUDITORDB_RefreshesHanging struct TALER_AUDITORDB_FeeTimeInconsistency { uint64_t row_id; + uint64_t problem_row_id; char *type; struct GNUNET_TIME_Absolute time; char *diagnostic; @@ -337,9 +351,11 @@ struct TALER_AUDITORDB_FeeTimeInconsistency 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; }; /** @@ -351,6 +367,7 @@ struct TALER_AUDITORDB_PurseNotClosedInconsistencies struct GNUNET_CRYPTO_EddsaPublicKey purse_pub; struct TALER_Amount amount; struct GNUNET_TIME_Absolute expiration_date; + bool suppressed; }; /** @@ -362,6 +379,7 @@ struct TALER_AUDITORDB_ReserveBalanceInsufficientInconsistency struct GNUNET_CRYPTO_EddsaPublicKey reserve_pub; bool inconsistency_gain; struct TALER_Amount inconsistency_amount; + bool suppressed; }; /** @@ -369,7 +387,7 @@ struct TALER_AUDITORDB_ReserveBalanceInsufficientInconsistency */ struct TALER_AUDITORDB_ReserveInInconsistency { - uint64_t row_id; + uint64_t bank_row_id; struct TALER_Amount amount_exchange_expected; struct TALER_Amount amount_wired; struct TALER_ReservePublicKeyP reserve_pub; @@ -397,14 +415,12 @@ struct TALER_AUDITORDB_Balances * 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_AmountArithmeticInconsistencyCallback)( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_AmountArithmeticInconsistency *dc); /** @@ -442,14 +458,12 @@ typedef enum GNUNET_GenericReturnValue * 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_BadSigLossesCallback)( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_BadSigLosses *dc); /** @@ -457,14 +471,12 @@ typedef enum GNUNET_GenericReturnValue * 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_ClosureLagsCallback)( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_ClosureLags *dc); /** @@ -472,14 +484,12 @@ typedef enum GNUNET_GenericReturnValue * 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_EmergencyCallback)( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_Emergency *dc); /** @@ -487,44 +497,26 @@ typedef enum GNUNET_GenericReturnValue * 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_EmergenciesByCountCallback)( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_EmergenciesByCount *dc); -/** - * Function called with progress 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_ProgressCallback)( - void *cls, - uint64_t serial_id, - const struct TALER_AUDITORDB_Progress *dc); /** * Function called with refreshes hanging 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_RefreshesHangingCallback)( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_RefreshesHanging *dc); /** @@ -532,14 +524,12 @@ typedef enum GNUNET_GenericReturnValue * 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_FeeTimeInconsistencyCallback)( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_FeeTimeInconsistency *dc); /** @@ -547,14 +537,12 @@ typedef enum GNUNET_GenericReturnValue * 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_DenominationKeyValidityWithdrawInconsistencyCallback)( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_DenominationKeyValidityWithdrawInconsistency *dc); @@ -563,14 +551,12 @@ typedef enum GNUNET_GenericReturnValue * 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_PurseNotClosedInconsistenciesCallback)( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_PurseNotClosedInconsistencies *dc); /** @@ -578,31 +564,24 @@ typedef enum GNUNET_GenericReturnValue * 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_ReserveBalanceInsufficientInconsistencyCallback)( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_ReserveBalanceInsufficientInconsistency *dc); -/** - * Function called with reserve balance insufficient inconsistency stored in - * the auditor's database. - * - * @param cls closure - * @param serial_id location of the @a dc in the database - * @param dc the balance itself - * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating - */ typedef enum GNUNET_GenericReturnValue (*TALER_AUDITORDB_BalancesCallback)( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_Balances *dc); +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_ProgressPointsCallback)( + void *cls, + const struct TALER_AUDITORDB_Progress *pp); + /** * Balance values for a reserve (or all reserves). */ @@ -688,7 +667,6 @@ struct TALER_AUDITORDB_DenominationsWithoutSigs struct GNUNET_TIME_Absolute start_time; struct GNUNET_TIME_Absolute end_time; bool suppressed; - }; struct TALER_AUDITORDB_MisattributionInInconsistency @@ -781,7 +759,7 @@ struct TALER_AUDITORDB_WireFormatInconsistency { uint64_t row_id; struct TALER_Amount amount; - int64_t wire_offset; + uint64_t wire_offset; char *diagnostic; bool suppressed; @@ -791,7 +769,8 @@ struct TALER_AUDITORDB_WireOutInconsistency { uint64_t row_id; char *destination_account; - char *diagnostic; // FIXME: new + char *diagnostic; + uint64_t wire_out_row_id; struct TALER_Amount expected; struct TALER_Amount claimed; bool suppressed; @@ -802,11 +781,12 @@ 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; @@ -833,14 +813,12 @@ struct TALER_AUDITORDB_ReserveNotClosedInconsistency * the auditor's database. * * @param cls closure - * @param serial_id location of the @a dc in the database * @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, - uint64_t serial_id, const struct TALER_AUDITORDB_DepositConfirmation *dc); @@ -889,20 +867,16 @@ typedef enum GNUNET_GenericReturnValue typedef enum GNUNET_GenericReturnValue (*TALER_AUDITORDB_ReserveNotClosedInconsistencyCallback)( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_ReserveNotClosedInconsistency *dc); typedef enum GNUNET_GenericReturnValue (*TALER_AUDITORDB_DenominationsWithoutSigsCallback)( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_DenominationsWithoutSigs *dc); - typedef enum GNUNET_GenericReturnValue (*TALER_AUDITORDB_MisattributionInInconsistencyCallback)( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_MisattributionInInconsistency *dc); typedef enum GNUNET_GenericReturnValue @@ -945,34 +919,24 @@ typedef enum GNUNET_GenericReturnValue typedef enum GNUNET_GenericReturnValue (*TALER_AUDITORDB_WireFormatInconsistencyCallback)( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_WireFormatInconsistency *dc); typedef enum GNUNET_GenericReturnValue (*TALER_AUDITORDB_WireOutInconsistencyCallback)( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_WireOutInconsistency *dc); typedef enum GNUNET_GenericReturnValue (*TALER_AUDITORDB_ReserveBalanceSummaryWrongInconsistencyCallback)( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_ReserveBalanceSummaryWrongInconsistency *dc); typedef enum GNUNET_GenericReturnValue (*TALER_AUDITORDB_RowMinorInconsistenciesCallback)( void *cls, - uint64_t serial_id, const struct TALER_AUDITORDB_RowMinorInconsistencies *dc); -typedef enum GNUNET_GenericReturnValue -(*TALER_AUDITORDB_FeeTimeInconsistencyCallback)( - void *cls, - uint64_t serial_id, - const struct TALER_AUDITORDB_FeeTimeInconsistency *dc); - /** * @brief The plugin API, returned from the plugin's "init" function. * The argument given to "init" is simply a configuration handle. @@ -1004,7 +968,7 @@ struct TALER_AUDITORDB_Plugin * #GNUNET_SYSERR if we have no DB connection */ enum GNUNET_GenericReturnValue - (*preflight)(void *cls); + (*preflight)(void *cls); /** @@ -1061,8 +1025,8 @@ struct TALER_AUDITORDB_Plugin * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure */ enum GNUNET_GenericReturnValue - (*drop_tables)(void *cls, - bool drop_exchangelist); + (*drop_tables)(void *cls, + bool drop_exchangelist); /** @@ -1074,9 +1038,9 @@ struct TALER_AUDITORDB_Plugin * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure */ enum GNUNET_GenericReturnValue - (*create_tables)(void *cls, - bool support_partitions, - uint32_t num_partitions); + (*create_tables)(void *cls, + bool support_partitions, + uint32_t num_partitions); /** @@ -1086,7 +1050,7 @@ struct TALER_AUDITORDB_Plugin * @return #GNUNET_OK on success */ enum GNUNET_GenericReturnValue - (*start)(void *cls); + (*start)(void *cls); /** @@ -1096,7 +1060,7 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*commit)(void *cls); + (*commit)(void *cls); /** @@ -1117,7 +1081,7 @@ struct TALER_AUDITORDB_Plugin * #GNUNET_SYSERR on DB errors */ enum GNUNET_GenericReturnValue - (*gc)(void *cls); + (*gc)(void *cls); /** @@ -1131,7 +1095,7 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*insert_auditor_progress)( + (*insert_auditor_progress)( void *cls, const char *progress_key, uint64_t progress_offset, @@ -1148,7 +1112,7 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*update_auditor_progress)( + (*update_auditor_progress)( void *cls, const char *progress_key, uint64_t progress_offset, @@ -1164,10 +1128,10 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*get_auditor_progress)(void *cls, - const char *progress_key, - uint64_t *progress_offset, - ...); + (*get_auditor_progress)(void *cls, + const char *progress_key, + uint64_t *progress_offset, + ...); /** @@ -1181,10 +1145,10 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*insert_balance)(void *cls, - const char *balance_key, - const struct TALER_Amount *balance_value, - ...); + (*insert_balance)(void *cls, + const char *balance_key, + const struct TALER_Amount *balance_value, + ...); /** @@ -1198,10 +1162,10 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*update_balance)(void *cls, - const char *balance_key, - const struct TALER_Amount *balance_amount, - ...); + (*update_balance)(void *cls, + const char *balance_key, + const struct TALER_Amount *balance_amount, + ...); /** @@ -1214,13 +1178,45 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*get_balance)(void *cls, - const char *balance_key, - struct TALER_Amount *balance_value, - ...); + (*get_balance)(void *cls, + const char *balance_key, + struct TALER_Amount *balance_value, + ...); /** + * Get information about balances from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param balance_key only return this particular balance + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ + enum GNUNET_DB_QueryStatus + (*get_balances)( + void *cls, + const char *balance_key, + TALER_AUDITORDB_BalancesCallback cb, + void *cb_cls); + + /** + * 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 + (*get_progress_points)( + void *cls, + const char *progress_key, + TALER_AUDITORDB_ProgressPointsCallback cb, + void *cb_cls); + + /** * Insert information about a signing key of the exchange. * * @param cls the @e cls of this struct with the plugin-specific state @@ -1228,7 +1224,7 @@ struct TALER_AUDITORDB_Plugin * @return query result status */ enum GNUNET_DB_QueryStatus - (*insert_exchange_signkey)( + (*insert_exchange_signkey)( void *cls, const struct TALER_AUDITORDB_ExchangeSigningKey *sk); @@ -1241,7 +1237,7 @@ struct TALER_AUDITORDB_Plugin * @return query result status */ enum GNUNET_DB_QueryStatus - (*insert_deposit_confirmation)( + (*insert_deposit_confirmation)( void *cls, const struct TALER_AUDITORDB_DepositConfirmation *dc); @@ -1258,7 +1254,7 @@ struct TALER_AUDITORDB_Plugin * @return query result status */ enum GNUNET_DB_QueryStatus - (*get_deposit_confirmations)( + (*get_deposit_confirmations)( void *cls, int64_t limit, uint64_t offset, @@ -1267,18 +1263,6 @@ struct TALER_AUDITORDB_Plugin void *cb_cls); - /** - * Delete information about a deposit confirmation from the database. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param row_id row to delete - * @return query result status - */ - enum GNUNET_DB_QueryStatus - (*delete_deposit_confirmation)( - void *cls, - uint64_t row_id); - // MARK: CRUD /** @@ -1293,7 +1277,7 @@ struct TALER_AUDITORDB_Plugin * @return query result status */ enum GNUNET_DB_QueryStatus - (*get_amount_arithmetic_inconsistency)( + (*get_amount_arithmetic_inconsistency)( void *cls, int64_t limit, uint64_t offset, @@ -1302,7 +1286,7 @@ struct TALER_AUDITORDB_Plugin void *cb_cls); enum GNUNET_DB_QueryStatus - (*get_coin_inconsistency)( + (*get_coin_inconsistency)( void *cls, int64_t limit, uint64_t offset, @@ -1311,7 +1295,7 @@ struct TALER_AUDITORDB_Plugin void *cb_cls); enum GNUNET_DB_QueryStatus - (*get_row_inconsistency)( + (*get_row_inconsistency)( void *cls, int64_t limit, uint64_t offset, @@ -1320,7 +1304,7 @@ struct TALER_AUDITORDB_Plugin void *cb_cls); enum GNUNET_DB_QueryStatus - (*get_emergency)( + (*get_emergency)( void *cls, int64_t limit, uint64_t offset, @@ -1329,7 +1313,7 @@ struct TALER_AUDITORDB_Plugin void *cb_cls); enum GNUNET_DB_QueryStatus - (*get_emergency_by_count)( + (*get_emergency_by_count)( void *cls, int64_t limit, uint64_t offset, @@ -1338,7 +1322,7 @@ struct TALER_AUDITORDB_Plugin void *cb_cls); enum GNUNET_DB_QueryStatus - (*get_denomination_key_validity_withdraw_inconsistency)( + (*get_denomination_key_validity_withdraw_inconsistency)( void *cls, int64_t limit, uint64_t offset, @@ -1347,7 +1331,7 @@ struct TALER_AUDITORDB_Plugin void *cb_cls); enum GNUNET_DB_QueryStatus - (*get_purse_not_closed_inconsistencies)( + (*get_purse_not_closed_inconsistencies)( void *cls, int64_t limit, uint64_t offset, @@ -1356,7 +1340,7 @@ struct TALER_AUDITORDB_Plugin void *cb_cls); enum GNUNET_DB_QueryStatus - (*get_reserve_balance_insufficient_inconsistency)( + (*get_reserve_balance_insufficient_inconsistency)( void *cls, int64_t limit, uint64_t offset, @@ -1365,19 +1349,18 @@ struct TALER_AUDITORDB_Plugin void *cb_cls); enum GNUNET_DB_QueryStatus - (*get_bad_sig_losses)( + (*get_bad_sig_losses)( void *cls, int64_t limit, uint64_t offset, bool return_suppressed, - bool filter_spec_pub, - struct GNUNET_CRYPTO_EddsaPublicKey op_spec_pub, + const struct GNUNET_CRYPTO_EddsaPublicKey *op_spec_pub, const char *op, TALER_AUDITORDB_BadSigLossesCallback cb, void *cb_cls); enum GNUNET_DB_QueryStatus - (*get_auditor_closure_lags)( + (*get_auditor_closure_lags)( void *cls, int64_t limit, uint64_t offset, @@ -1386,16 +1369,7 @@ struct TALER_AUDITORDB_Plugin void *cb_cls); enum GNUNET_DB_QueryStatus - (*get_progress)( - void *cls, - int64_t limit, - uint64_t offset, - bool return_suppressed, - TALER_AUDITORDB_ProgressCallback cb, - void *cb_cls); - - enum GNUNET_DB_QueryStatus - (*get_refreshes_hanging)( + (*get_refreshes_hanging)( void *cls, int64_t limit, uint64_t offset, @@ -1411,62 +1385,62 @@ struct TALER_AUDITORDB_Plugin * @return query result status */ enum GNUNET_DB_QueryStatus - (*delete_amount_arithmetic_inconsistency)( + (*delete_amount_arithmetic_inconsistency)( void *cls, uint64_t row_id); enum GNUNET_DB_QueryStatus - (*delete_coin_inconsistency)( + (*delete_coin_inconsistency)( void *cls, uint64_t row_id); enum GNUNET_DB_QueryStatus - (*delete_row_inconsistency)( + (*delete_row_inconsistency)( void *cls, uint64_t row_id); enum GNUNET_DB_QueryStatus - (*delete_emergency)( + (*delete_emergency)( void *cls, uint64_t row_id); enum GNUNET_DB_QueryStatus - (*delete_emergency_by_count)( + (*delete_emergency_by_count)( void *cls, uint64_t row_id); enum GNUNET_DB_QueryStatus - (*delete_denomination_key_validity_withdraw_inconsistency)( + (*delete_denomination_key_validity_withdraw_inconsistency)( void *cls, uint64_t row_id); enum GNUNET_DB_QueryStatus - (*delete_purse_not_closed_inconsistencies)( + (*delete_purse_not_closed_inconsistencies)( void *cls, uint64_t row_id); enum GNUNET_DB_QueryStatus - (*delete_reserve_balance_insufficient_inconsistency)( + (*delete_reserve_balance_insufficient_inconsistency)( void *cls, uint64_t row_id); enum GNUNET_DB_QueryStatus - (*delete_bad_sig_losses)( + (*delete_bad_sig_losses)( void *cls, uint64_t row_id); enum GNUNET_DB_QueryStatus - (*delete_auditor_closure_lags)( + (*delete_auditor_closure_lags)( void *cls, uint64_t row_id); enum GNUNET_DB_QueryStatus - (*delete_progress)( + (*delete_progress)( void *cls, uint64_t row_id); enum GNUNET_DB_QueryStatus - (*delete_refreshes_hanging)( + (*delete_refreshes_hanging)( void *cls, uint64_t row_id); @@ -1479,145 +1453,76 @@ struct TALER_AUDITORDB_Plugin * @return query result status */ enum GNUNET_DB_QueryStatus - (*insert_amount_arithmetic_inconsistency)( + (*insert_amount_arithmetic_inconsistency)( void *cls, const struct TALER_AUDITORDB_AmountArithmeticInconsistency *dc); enum GNUNET_DB_QueryStatus - (*insert_coin_inconsistency)( + (*insert_coin_inconsistency)( void *cls, const struct TALER_AUDITORDB_CoinInconsistency *dc); enum GNUNET_DB_QueryStatus - (*insert_row_inconsistency)( + (*insert_row_inconsistency)( void *cls, const struct TALER_AUDITORDB_RowInconsistency *dc); enum GNUNET_DB_QueryStatus - (*insert_emergency)( + (*insert_emergency)( void *cls, const struct TALER_AUDITORDB_Emergency *dc); enum GNUNET_DB_QueryStatus - (*insert_emergency_by_count)( + (*insert_emergency_by_count)( void *cls, const struct TALER_AUDITORDB_EmergenciesByCount *dc); enum GNUNET_DB_QueryStatus - (*insert_denomination_key_validity_withdraw_inconsistency)( + (*insert_denomination_key_validity_withdraw_inconsistency)( void *cls, const struct TALER_AUDITORDB_DenominationKeyValidityWithdrawInconsistency *dc); enum GNUNET_DB_QueryStatus - (*insert_purse_not_closed_inconsistencies)( + (*insert_purse_not_closed_inconsistencies)( void *cls, const struct TALER_AUDITORDB_PurseNotClosedInconsistencies *dc); enum GNUNET_DB_QueryStatus - (*insert_reserve_balance_insufficient_inconsistency)( + (*insert_reserve_balance_insufficient_inconsistency)( void *cls, const struct TALER_AUDITORDB_ReserveBalanceInsufficientInconsistency *dc); enum GNUNET_DB_QueryStatus - (*insert_bad_sig_losses)( + (*insert_bad_sig_losses)( void *cls, const struct TALER_AUDITORDB_BadSigLosses *dc); enum GNUNET_DB_QueryStatus - (*insert_auditor_closure_lags)( + (*insert_auditor_closure_lags)( void *cls, const struct TALER_AUDITORDB_ClosureLags *dc); - enum GNUNET_DB_QueryStatus - (*insert_progress)( - void *cls, - const struct TALER_AUDITORDB_Progress *dc); - - enum GNUNET_DB_QueryStatus - (*insert_refreshes_hanging)( + (*insert_refreshes_hanging)( void *cls, const struct TALER_AUDITORDB_RefreshesHanging *dc); enum GNUNET_DB_QueryStatus - (*update_bad_sig_losses)( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu); - - enum GNUNET_DB_QueryStatus - (*update_generic_suppressed)( + (*update_generic_suppressed)( void *cls, - enum TALER_AUDITORDB_SuppressableTables table, + enum TALER_AUDITORDB_DeletableSuppressableTables table, uint64_t row_id, bool suppressed); - enum GNUNET_DB_QueryStatus - (*update_emergency_by_count)( + (*delete_generic)( void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu); - - - enum GNUNET_DB_QueryStatus - (*update_row_inconsistency)( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu); - - - enum GNUNET_DB_QueryStatus - (*update_purse_not_closed_inconsistencies)( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu); - - - enum GNUNET_DB_QueryStatus - (*update_reserve_balance_insufficient_inconsistency)( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu); - - - enum GNUNET_DB_QueryStatus - (*update_coin_inconsistency)( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu); - - enum GNUNET_DB_QueryStatus - (*update_denomination_key_validity_withdraw_inconsistency)( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu); - - - enum GNUNET_DB_QueryStatus - (*update_refreshes_hanging)( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu); - - - enum GNUNET_DB_QueryStatus - (*update_emergency)( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu); - - - enum GNUNET_DB_QueryStatus - (*update_closure_lags)( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu); - - enum GNUNET_DB_QueryStatus - (*update_amount_arithmetic_inconsistency)( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu); - - enum GNUNET_DB_QueryStatus - (*update_deposit_confirmations)( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu); - + enum TALER_AUDITORDB_DeletableSuppressableTables table, + uint64_t row_id); enum GNUNET_DB_QueryStatus - (*get_reserve_in_inconsistency)( + (*get_reserve_in_inconsistency)( void *cls, int64_t limit, uint64_t offset, @@ -1627,25 +1532,18 @@ struct TALER_AUDITORDB_Plugin enum GNUNET_DB_QueryStatus - (*delete_reserve_in_inconsistency)( + (*delete_reserve_in_inconsistency)( void *cls, uint64_t row_id); enum GNUNET_DB_QueryStatus - (*insert_reserve_in_inconsistency)( + (*insert_reserve_in_inconsistency)( void *cls, const struct TALER_AUDITORDB_ReserveInInconsistency *dc); - enum GNUNET_DB_QueryStatus - (*update_reserve_in_inconsistency)( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu); - - - enum GNUNET_DB_QueryStatus - (*get_reserve_not_closed_inconsistency)( + (*get_reserve_not_closed_inconsistency)( void *cls, int64_t limit, uint64_t offset, @@ -1655,25 +1553,18 @@ struct TALER_AUDITORDB_Plugin enum GNUNET_DB_QueryStatus - (*delete_reserve_not_closed_inconsistency)( + (*delete_reserve_not_closed_inconsistency)( void *cls, uint64_t row_id); enum GNUNET_DB_QueryStatus - (*insert_reserve_not_closed_inconsistency)( + (*insert_reserve_not_closed_inconsistency)( void *cls, const struct TALER_AUDITORDB_ReserveNotClosedInconsistency *dc); - - enum GNUNET_DB_QueryStatus - (*update_reserve_not_closed_inconsistency)( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu); - - enum GNUNET_DB_QueryStatus - (*get_denominations_without_sigs)( + (*get_denominations_without_sigs)( void *cls, int64_t limit, uint64_t offset, @@ -1683,25 +1574,18 @@ struct TALER_AUDITORDB_Plugin enum GNUNET_DB_QueryStatus - (*delete_denominations_without_sigs)( + (*delete_denominations_without_sigs)( void *cls, uint64_t row_id); enum GNUNET_DB_QueryStatus - (*insert_denominations_without_sigs)( + (*insert_denominations_without_sigs)( void *cls, const struct TALER_AUDITORDB_DenominationsWithoutSigs *dc); - - enum GNUNET_DB_QueryStatus - (*update_denominations_without_sigs)( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu); - - enum GNUNET_DB_QueryStatus - (*get_misattribution_in_inconsistency)( + (*get_misattribution_in_inconsistency)( void *cls, int64_t limit, uint64_t offset, @@ -1711,79 +1595,58 @@ struct TALER_AUDITORDB_Plugin enum GNUNET_DB_QueryStatus - (*delete_misattribution_in_inconsistency)( + (*delete_misattribution_in_inconsistency)( void *cls, uint64_t row_id); enum GNUNET_DB_QueryStatus - (*insert_misattribution_in_inconsistency)( + (*insert_misattribution_in_inconsistency)( void *cls, const struct TALER_AUDITORDB_MisattributionInInconsistency *dc); - enum GNUNET_DB_QueryStatus - (*update_misattribution_in_inconsistency)( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu); - - - enum GNUNET_DB_QueryStatus - (*get_reserves)( + (*get_reserves)( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, TALER_AUDITORDB_ReservesCallback cb, void *cb_cls); - enum GNUNET_DB_QueryStatus - (*delete_reserves)( - void *cls, - uint64_t row_id); - - enum GNUNET_DB_QueryStatus - (*get_purses)( + (*get_purses)( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, TALER_AUDITORDB_PursesCallback cb, void *cb_cls); enum GNUNET_DB_QueryStatus - (*delete_purses)( + (*delete_purses)( void *cls, uint64_t row_id); enum GNUNET_DB_QueryStatus - (*get_denomination_pending)( + (*get_denomination_pending)( void *cls, int64_t limit, uint64_t offset, - bool return_suppressed, TALER_AUDITORDB_DenominationPendingCallback cb, void *cb_cls); enum GNUNET_DB_QueryStatus - (*delete_denomination_pending)( + (*delete_denomination_pending)( void *cls, uint64_t row_id); enum GNUNET_DB_QueryStatus - (*insert_denomination_pending)( + (*insert_denomination_pending)( void *cls, const struct TALER_AUDITORDB_DenominationPending *dc); enum GNUNET_DB_QueryStatus - (*update_denomination_pending)( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu); - - enum GNUNET_DB_QueryStatus - (*get_exchange_signkeys)( + (*get_exchange_signkeys)( void *cls, int64_t limit, uint64_t offset, @@ -1792,7 +1655,7 @@ struct TALER_AUDITORDB_Plugin void *cb_cls); enum GNUNET_DB_QueryStatus - (*get_wire_format_inconsistency)( + (*get_wire_format_inconsistency)( void *cls, int64_t limit, uint64_t offset, @@ -1802,25 +1665,18 @@ struct TALER_AUDITORDB_Plugin enum GNUNET_DB_QueryStatus - (*delete_wire_format_inconsistency)( + (*delete_wire_format_inconsistency)( void *cls, uint64_t row_id); enum GNUNET_DB_QueryStatus - (*insert_wire_format_inconsistency)( + (*insert_wire_format_inconsistency)( void *cls, const struct TALER_AUDITORDB_WireFormatInconsistency *dc); - enum GNUNET_DB_QueryStatus - (*update_wire_format_inconsistency)( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu); - - - enum GNUNET_DB_QueryStatus - (*get_wire_out_inconsistency)( + (*get_wire_out_inconsistency)( void *cls, int64_t limit, uint64_t offset, @@ -1830,25 +1686,23 @@ struct TALER_AUDITORDB_Plugin enum GNUNET_DB_QueryStatus - (*delete_wire_out_inconsistency)( + (*delete_wire_out_inconsistency)( void *cls, uint64_t row_id); enum GNUNET_DB_QueryStatus - (*insert_wire_out_inconsistency)( + (*insert_wire_out_inconsistency)( void *cls, const struct TALER_AUDITORDB_WireOutInconsistency *dc); - enum GNUNET_DB_QueryStatus - (*update_wire_out_inconsistency)( + (*delete_wire_out_inconsistency_if_matching)( void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu); - + const struct TALER_AUDITORDB_WireOutInconsistency *dc); enum GNUNET_DB_QueryStatus - (*get_reserve_balance_summary_wrong_inconsistency)( + (*get_reserve_balance_summary_wrong_inconsistency)( void *cls, int64_t limit, uint64_t offset, @@ -1858,25 +1712,18 @@ struct TALER_AUDITORDB_Plugin enum GNUNET_DB_QueryStatus - (*delete_reserve_balance_summary_wrong_inconsistency)( + (*delete_reserve_balance_summary_wrong_inconsistency)( void *cls, uint64_t row_id); enum GNUNET_DB_QueryStatus - (*insert_reserve_balance_summary_wrong_inconsistency)( + (*insert_reserve_balance_summary_wrong_inconsistency)( void *cls, const struct TALER_AUDITORDB_ReserveBalanceSummaryWrongInconsistency *dc); - enum GNUNET_DB_QueryStatus - (*update_reserve_balance_summary_wrong_inconsistency)( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu); - - - enum GNUNET_DB_QueryStatus - (*get_row_minor_inconsistencies)( + (*get_row_minor_inconsistencies)( void *cls, int64_t limit, uint64_t offset, @@ -1886,25 +1733,18 @@ struct TALER_AUDITORDB_Plugin enum GNUNET_DB_QueryStatus - (*delete_row_minor_inconsistencies)( + (*delete_row_minor_inconsistencies)( void *cls, uint64_t row_id); enum GNUNET_DB_QueryStatus - (*insert_row_minor_inconsistencies)( + (*insert_row_minor_inconsistencies)( void *cls, const struct TALER_AUDITORDB_RowMinorInconsistencies *dc); - - enum GNUNET_DB_QueryStatus - (*update_row_minor_inconsistencies)( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu); - - enum GNUNET_DB_QueryStatus - (*get_fee_time_inconsistency)( + (*get_fee_time_inconsistency)( void *cls, int64_t limit, uint64_t offset, @@ -1914,32 +1754,16 @@ struct TALER_AUDITORDB_Plugin enum GNUNET_DB_QueryStatus - (*delete_fee_time_inconsistency)( + (*delete_fee_time_inconsistency)( void *cls, uint64_t row_id); enum GNUNET_DB_QueryStatus - (*insert_fee_time_inconsistency)( + (*insert_fee_time_inconsistency)( void *cls, const struct TALER_AUDITORDB_FeeTimeInconsistency *dc); - - enum GNUNET_DB_QueryStatus - (*update_fee_time_inconsistency)( - void *cls, - const struct TALER_AUDITORDB_Generic_Update *gu); - - enum GNUNET_DB_QueryStatus - (*get_balances)( - void *cls, - int64_t limit, - uint64_t offset, - bool return_suppressed, - const char *balance_key, - TALER_AUDITORDB_BalancesCallback cb, - void *cb_cls); - /** * Insert information about a reserve. There must not be an * existing record for the reserve. @@ -1952,7 +1776,7 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*insert_reserve_info)( + (*insert_reserve_info)( void *cls, const struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_AUDITORDB_ReserveFeeBalance *rfb, @@ -1971,7 +1795,7 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*update_reserve_info)( + (*update_reserve_info)( void *cls, const struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_AUDITORDB_ReserveFeeBalance *rfb, @@ -1990,7 +1814,7 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*get_reserve_info)( + (*get_reserve_info)( void *cls, const struct TALER_ReservePublicKeyP *reserve_pub, uint64_t *rowid, @@ -2007,8 +1831,8 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*del_reserve_info)(void *cls, - const struct TALER_ReservePublicKeyP *reserve_pub); + (*del_reserve_info)(void *cls, + const struct TALER_ReservePublicKeyP *reserve_pub); /** @@ -2022,7 +1846,7 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*insert_pending_deposit)( + (*insert_pending_deposit)( void *cls, uint64_t batch_deposit_serial_id, const struct TALER_PaytoHashP *wire_target_h_payto, @@ -2040,7 +1864,7 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*delete_pending_deposit)( + (*delete_pending_deposit)( void *cls, uint64_t batch_deposit_serial_id); @@ -2055,7 +1879,7 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*select_pending_deposits)( + (*select_pending_deposits)( void *cls, struct GNUNET_TIME_Absolute deadline, TALER_AUDITORDB_WireMissingCallback cb, @@ -2073,7 +1897,7 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*insert_purse_info)( + (*insert_purse_info)( void *cls, const struct TALER_PurseContractPublicKeyP *purse_pub, const struct TALER_Amount *balance, @@ -2090,7 +1914,7 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*update_purse_info)( + (*update_purse_info)( void *cls, const struct TALER_PurseContractPublicKeyP *purse_pub, const struct TALER_Amount *balance); @@ -2107,7 +1931,7 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*get_purse_info)( + (*get_purse_info)( void *cls, const struct TALER_PurseContractPublicKeyP *purse_pub, uint64_t *rowid, @@ -2123,7 +1947,7 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*delete_purse_info)( + (*delete_purse_info)( void *cls, const struct TALER_PurseContractPublicKeyP *purse_pub); @@ -2137,7 +1961,7 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*select_purse_expired)( + (*select_purse_expired)( void *cls, TALER_AUDITORDB_ExpiredPurseCallback cb, void *cb_cls); @@ -2153,7 +1977,7 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*insert_denomination_balance)( + (*insert_denomination_balance)( void *cls, const struct TALER_DenominationHashP *denom_pub_hash, const struct TALER_AUDITORDB_DenominationCirculationData *dcd); @@ -2169,7 +1993,7 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*update_denomination_balance)( + (*update_denomination_balance)( void *cls, const struct TALER_DenominationHashP *denom_pub_hash, const struct TALER_AUDITORDB_DenominationCirculationData *dcd); @@ -2182,7 +2006,7 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*del_denomination_balance)( + (*del_denomination_balance)( void *cls, const struct TALER_DenominationHashP *denom_pub_hash); @@ -2196,7 +2020,7 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*get_denomination_balance)( + (*get_denomination_balance)( void *cls, const struct TALER_DenominationHashP *denom_pub_hash, struct TALER_AUDITORDB_DenominationCirculationData *dcd); @@ -2216,7 +2040,7 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*insert_historic_denom_revenue)( + (*insert_historic_denom_revenue)( void *cls, const struct TALER_DenominationHashP *denom_pub_hash, struct GNUNET_TIME_Timestamp revenue_timestamp, @@ -2233,7 +2057,7 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*select_historic_denom_revenue)( + (*select_historic_denom_revenue)( void *cls, int64_t limit, uint64_t offset, @@ -2251,7 +2075,7 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*insert_historic_reserve_revenue)( + (*insert_historic_reserve_revenue)( void *cls, struct GNUNET_TIME_Timestamp start_time, struct GNUNET_TIME_Timestamp end_time, @@ -2267,7 +2091,7 @@ struct TALER_AUDITORDB_Plugin * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*select_historic_reserve_revenue)( + (*select_historic_reserve_revenue)( void *cls, int64_t limit, uint64_t offset, diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index ac95e4756..29796cadc 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -2465,7 +2465,7 @@ struct TALER_TokenUseMerchantValues /** * The blinded token use public key of a token. Ready to be signed by the merchant. */ -struct TALER_TokenEnvelopeP +struct TALER_TokenEnvelope { /** * Blinded public key of the token. @@ -2539,7 +2539,7 @@ TALER_token_use_blinding_secret_create ( * @return singleton to use for RSA blinding */ const struct TALER_TokenUseMerchantValues * -TALER_token_blind_input_rsa_singleton (); +TALER_token_blind_input_rsa_singleton (void); /** @@ -2566,7 +2566,7 @@ TALER_token_blind_input_copy (struct TALER_TokenUseMerchantValues *bi_dst, */ enum GNUNET_GenericReturnValue TALER_token_issue_sign (const struct TALER_TokenIssuePrivateKeyP *issue_priv, - const struct TALER_TokenEnvelopeP *envelope, + const struct TALER_TokenEnvelope *envelope, struct TALER_TokenIssueBlindSignatureP *issue_sig); diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index b778fcceb..2aaa02d0a 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -36,7 +36,40 @@ * Version of the Taler Exchange API, in hex. * Thus 0.8.4-1 = 0x00080401. */ -#define TALER_EXCHANGE_API_VERSION 0x00100001 +#define TALER_EXCHANGE_API_VERSION 0x00100005 + +/** + * Information returned when a client needs to pass + * a KYC check before the transaction may succeed. + */ +struct TALER_EXCHANGE_KycNeededRedirect +{ + + /** + * Hash of the payto-URI of the account to KYC; + */ + struct TALER_PaytoHashP h_payto; + + /** + * Public key needed to access the KYC state of + * this account. All zeros if a wire transfer + * is required first to establish the key. + */ + union TALER_AccountPublicKeyP account_pub; + + /** + * Legitimization requirement that the merchant should use + * to check for its KYC status, 0 if not known. + */ + uint64_t requirement_row; + + /** + * Set to true if the KYC AUTH public key known to the exchange does not + * match the merchant public key associated with the deposit operation. + */ + bool bad_kyc_auth; +}; + /* ********************* /keys *********************** */ @@ -422,6 +455,55 @@ struct TALER_EXCHANGE_WireAccount /** + * Applicable soft limits of zero for an account (or wallet). + * Clients should begin a KYC process before attempting + * these operations. + */ +struct TALER_EXCHANGE_ZeroLimitedOperation +{ + + /** + * Operation type for which the restriction applies. + */ + enum TALER_KYCLOGIC_KycTriggerEvent operation_type; + +}; + + +/** + * Applicable limits for an account (or wallet). Exceeding these limits may + * trigger additional KYC requirements or be categorically verboten. + */ +struct TALER_EXCHANGE_AccountLimit +{ + + /** + * Operation type for which the restriction applies. + */ + enum TALER_KYCLOGIC_KycTriggerEvent operation_type; + + /** + * Timeframe over which the @e threshold is computed. + */ + struct GNUNET_TIME_Relative timeframe; + + /** + * The maximum amount transacted within the given @e timeframe for the + * specified @e operation_type. + */ + struct TALER_Amount threshold; + + /** + * True if this is a soft limit and passing KYC checks + * or AML reviews may raise this limit. False if this + * is a hard limit that the exchange will not permit + * the client to exceed. + */ + bool soft_limit; +}; + + +/** * @brief Information about keys from the exchange. */ struct TALER_EXCHANGE_Keys @@ -502,6 +584,20 @@ struct TALER_EXCHANGE_Keys struct TALER_EXCHANGE_WireAccount *accounts; /** + * Array of hard limits that apply at this exchange. + * All limits in this array will be hard limits. + */ + struct TALER_EXCHANGE_AccountLimit *hard_limits; + + /** + * Array of operations with a default soft limit of zero + * that apply at this exchange. + * Clients should begin a KYC process before attempting + * these operations. + */ + struct TALER_EXCHANGE_ZeroLimitedOperation *zero_limits; + + /** * Array of wire fees by wire method. */ struct TALER_EXCHANGE_WireFeesByMethod *fees; @@ -551,20 +647,6 @@ struct TALER_EXCHANGE_Keys struct TALER_Amount stefan_log; /** - * Maximum amount for an individual transaction. - * Set to an invalid amount (see #TALER_amount_is_valid()) - * if there is no limit. - */ - struct TALER_Amount transaction_limit; - - /** - * Maximum amount that can be refunded per individual transaction. - * Set to an invalid amount (see #TALER_amount_is_valid()) - * if there is no limit. - */ - struct TALER_Amount refund_limit; - - /** * Linear STEFAN parameter. */ double stefan_lin; @@ -580,6 +662,16 @@ struct TALER_EXCHANGE_Keys unsigned int fees_len; /** + * Length of @e hard_limits array. + */ + unsigned int hard_limits_length; + + /** + * Length of @e zero_limits array. + */ + unsigned int zero_limits_length; + + /** * Length of the @e wallet_balance_limit_without_kyc * array. */ @@ -927,6 +1019,62 @@ TALER_EXCHANGE_test_signing_key ( /** + * Check if a wire transfer is allowed between + * @a account if the exchange and @a payto_uri. + * + * @param account exchange account to check + * @param check_credit true for credit (sending money + * to the exchange), false for debit (receiving money + * from the exchange) + * @param payto_uri other bank account (merchant, customer) + * @return + * #GNUNET_YES if the exchange would allow this + * #GNUNET_NO if this is not allowed + * #GNUNET_SYSERR if data in @a account is malformed + * or we experienced internal errors + */ +enum GNUNET_GenericReturnValue +TALER_EXCHANGE_test_account_allowed ( + const struct TALER_EXCHANGE_WireAccount *account, + bool check_credit, + const char *payto_uri); + + +/** + * Check the hard limits in @a keys for the given + * @a event and lower @a limit to the lowest applicable + * limit independent (!) of the timeframe. Useful + * to determine the absolute transaction limit. + * + * @param keys exchange keys to evaluate + * @param event trigger type to evaluate + * @param[in,out] limit to lower to the minimum limit + * that applies to @a event + */ +void +TALER_EXCHANGE_keys_evaluate_hard_limits ( + const struct TALER_EXCHANGE_Keys *keys, + enum TALER_KYCLOGIC_KycTriggerEvent event, + struct TALER_Amount *limit); + + +/** + * Check if a (soft) limit of zero applies for the + * given @a event under @a keys. + * + * @param keys exchange keys to evaluate + * @param event trigger type to evaluate + * @return true if the operation is soft-limited and + * thus KYC is required before the operation may be + * accepted at the exchange + */ +bool +TALER_EXCHANGE_keys_evaluate_zero_limits ( + const struct TALER_EXCHANGE_Keys *keys, + enum TALER_KYCLOGIC_KycTriggerEvent event); + + +/** * Obtain the denomination key details from the exchange. * * @param keys the exchange's key set @@ -1199,12 +1347,43 @@ struct TALER_EXCHANGE_BatchDepositResult struct { /** - * The coin that had a conflict. - */ - struct TALER_CoinSpendPublicKeyP coin_pub; + * Details depending on the @e hr.ec. + */ + union + { + struct + { + /** + * The coin that had a conflict. + */ + struct TALER_CoinSpendPublicKeyP coin_pub; + } insufficient_funds; + + struct + { + /** + * The coin that had a conflict. + */ + struct TALER_CoinSpendPublicKeyP coin_pub; + } coin_conflicting_age_hash; + + struct + { + /** + * The coin that had a conflict. + */ + struct TALER_CoinSpendPublicKeyP coin_pub; + } coin_conflicting_denomination_key; + + } details; } conflict; + /** + * Details if the status is #MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS. + */ + struct TALER_EXCHANGE_KycNeededRedirect unavailable_for_legal_reasons; + } details; }; @@ -2480,34 +2659,6 @@ TALER_EXCHANGE_reserves_history_cancel ( /** - * Information returned when a client needs to pass - * a KYC check before the transaction may succeed. - */ -struct TALER_EXCHANGE_KycNeededRedirect -{ - - /** - * Hash of the payto-URI of the account to KYC; - */ - struct TALER_PaytoHashP h_payto; - - /** - * Public key needed to access the KYC state of - * this account. All zeros if a wire transfer - * is required first to establish the key. - */ - union TALER_AccountPublicKeyP account_pub; - - /** - * Legitimization requirement that the merchant should use - * to check for its KYC status, 0 if not known. - */ - uint64_t requirement_row; - -}; - - -/** * Information input into the withdraw process per coin. */ struct TALER_EXCHANGE_WithdrawCoinInput @@ -3991,6 +4142,8 @@ struct TALER_EXCHANGE_GetDepositResponse /** * KYC legitimization requirement that the merchant should use to check * for its KYC status. + * + * @deprecated, no longer needed. */ uint64_t requirement_row; @@ -4265,39 +4418,6 @@ struct TALER_EXCHANGE_KycCheckHandle; /** - * Applicable limits for an account. Exceeding these limits may trigger - * additional KYC requirements or be categorically verboten. - */ -struct TALER_EXCHANGE_AccountLimit -{ - - /** - * Operation type for which the restriction applies. - */ - enum TALER_KYCLOGIC_KycTriggerEvent operation_type; - - /** - * Timeframe over which the @e threshold is computed. - */ - struct GNUNET_TIME_Relative timeframe; - - /** - * The maximum amount transacted within the given @e timeframe for the - * specified @e operation_type. - */ - struct TALER_Amount threshold; - - /** - * True if this is a soft limit and passing KYC checks - * or AML reviews may raise this limit. False if this - * is a hard limit that the exchange will not permit - * the client to exceed. - */ - bool soft_limit; -}; - - -/** * KYC/AML status information about an account. */ struct TALER_EXCHANGE_AccountKycStatus @@ -4355,6 +4475,19 @@ struct TALER_EXCHANGE_KycStatus */ struct TALER_EXCHANGE_AccountKycStatus accepted; + /** + * Request was forbidden. + */ + struct + { + + /** + * Account pub that would have been authorized. + */ + union TALER_AccountPublicKeyP expected_account_pub; + + } forbidden; + } details; }; @@ -4377,9 +4510,10 @@ typedef void * * @param ctx CURL context * @param url exchange base URL - * @param requirement_row number identifying the KYC requirement + * @param h_payto hash of the account the KYC check is about * @param pk private key to authorize the request with - * @param timeout how long to wait for a positive KYC status + * @param lpt target for long polling + * @param timeout how long to wait for an answer, including possibly long polling for the desired @a lpt status * @param cb function to call with the result * @param cb_cls closure for @a cb * @return NULL on error @@ -4388,8 +4522,9 @@ struct TALER_EXCHANGE_KycCheckHandle * TALER_EXCHANGE_kyc_check ( struct GNUNET_CURL_Context *ctx, const char *url, - uint64_t requirement_row, + const struct TALER_PaytoHashP *h_payto, const union TALER_AccountPrivateKeyP *pk, + enum TALER_EXCHANGE_KycLongPollTarget lpt, struct GNUNET_TIME_Relative timeout, TALER_EXCHANGE_KycStatusCallback cb, void *cb_cls); @@ -6344,10 +6479,14 @@ struct TALER_EXCHANGE_AccountRule * @param url HTTP base URL for the exchange * @param h_payto payto URI hash of the account the * decision is about + * @param payto_uri payto URI of the account, can + * be NULL if the exchange already knows the account * @param decision_time when was the decision made * @param successor_measure measure to activate after @a expiration_time if no rule applied - * @param new_check new KYC check to provide to the user, - * NULL for none + * @param new_measures space-separated list of measures + * to trigger immediately; + " "+" prefixed for AND combination; + * NULL for none * @param expiration_time when do the new rules expire * @param num_rules length of the @a rules array * @param rules new rules for the account @@ -6362,13 +6501,14 @@ struct TALER_EXCHANGE_AccountRule * @return the request handle; NULL upon error */ struct TALER_EXCHANGE_AddAmlDecision * -TALER_EXCHANGE_add_aml_decision ( +TALER_EXCHANGE_post_aml_decision ( struct GNUNET_CURL_Context *ctx, const char *url, const struct TALER_PaytoHashP *h_payto, + const char *payto_uri, struct GNUNET_TIME_Timestamp decision_time, const char *successor_measure, - const char *new_check, + const char *new_measures, struct GNUNET_TIME_Timestamp expiration_time, unsigned int num_rules, const struct TALER_EXCHANGE_AccountRule *rules, @@ -6383,12 +6523,12 @@ TALER_EXCHANGE_add_aml_decision ( /** - * Cancel #TALER_EXCHANGE_add_aml_decision() operation. + * Cancel #TALER_EXCHANGE_post_aml_decision() operation. * * @param rh handle of the operation to cancel */ void -TALER_EXCHANGE_add_aml_decision_cancel ( +TALER_EXCHANGE_post_aml_decision_cancel ( struct TALER_EXCHANGE_AddAmlDecision *rh); diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index 2037fde95..ea5c0b560 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -383,8 +383,9 @@ struct TALER_EXCHANGEDB_TableData struct { char *payto_uri; - struct TALER_AccountAccessTokenP target_token; - union TALER_AccountPublicKeyP account_pub; + struct TALER_AccountAccessTokenP access_token; + union TALER_AccountPublicKeyP target_pub; + bool no_account; } wire_targets; struct @@ -2956,6 +2957,14 @@ struct TALER_EXCHANGEDB_CsRevealFreshCoinData */ 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. @@ -2963,6 +2972,11 @@ struct TALER_EXCHANGEDB_KycStatus uint64_t requirement_row; /** + * True if @e account_pub is set. + */ + bool have_account_pub; + + /** * True if the KYC status is "satisfied". */ bool ok; @@ -3525,12 +3539,14 @@ typedef void * 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); @@ -3614,7 +3630,6 @@ typedef void * * @param cls closure * @param row_id current row in kyc_attributes table - * @param provider_name which provider collected the data, NULL for user upload * @param collection_time when were the attributes collected * @param enc_attributes_size size of @a enc_attributes * @param enc_attributes the encrypted collected attributes @@ -3623,7 +3638,6 @@ typedef void (*TALER_EXCHANGEDB_AmlAttributeCallback)( void *cls, uint64_t row_id, - const char *provider_name, struct GNUNET_TIME_Timestamp collection_time, size_t enc_attributes_size, const void *enc_attributes); @@ -4217,6 +4231,23 @@ struct TALER_EXCHANGEDB_Plugin /** + * 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 + (*do_check_deposit_idempotent)( + void *cls, + const struct TALER_EXCHANGEDB_BatchDeposit *bd, + struct GNUNET_TIME_Timestamp *exchange_timestamp, + bool *is_idempotent); + + + /** * Perform melt operation, checking for sufficient balance * of the coin and possibly persisting the melt details. * @@ -4854,6 +4885,7 @@ struct TALER_EXCHANGEDB_Plugin * 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 @@ -4869,6 +4901,7 @@ struct TALER_EXCHANGEDB_Plugin enum GNUNET_DB_QueryStatus (*get_coin_transactions)( void *cls, + bool begin_transaction, const struct TALER_CoinSpendPublicKeyP *coin_pub, uint64_t start_off, uint64_t etag_in, @@ -4926,6 +4959,7 @@ struct TALER_EXCHANGEDB_Plugin * @param[out] execution_time when was the transaction done, or * when we expect it to be done (if @a pending is false) * @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 @@ -4940,7 +4974,8 @@ struct TALER_EXCHANGEDB_Plugin struct GNUNET_TIME_Timestamp *exec_time, struct TALER_Amount *amount_with_fee, struct TALER_Amount *deposit_fee, - struct TALER_EXCHANGEDB_KycStatus *kyc); + struct TALER_EXCHANGEDB_KycStatus *kyc, + union TALER_AccountPublicKeyP *account_pub); /** @@ -6876,11 +6911,16 @@ struct TALER_EXCHANGEDB_Plugin * can be NULL if @a h_payto is already * guaranteed to be in wire_targets * @param h_payto hash of @a payto_uri - * @param account_pub public key to enable for the + * @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 @@ -6888,10 +6928,12 @@ struct TALER_EXCHANGEDB_Plugin void *cls, const char *payto_uri, const struct TALER_PaytoHashP *h_payto, - const union TALER_AccountPublicKeyP *account_pub, + 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); + uint64_t *requirement_row, + bool *bad_kyc_auth); /** @@ -6975,27 +7017,27 @@ struct TALER_EXCHANGEDB_Plugin * Lookup KYC requirement. * * @param cls closure - * @param requirement_row identifies requirement to look up (in legitimization_measures table) - * @param[out] account_pub set to public key of the account - * needed to authorize access, all zeros if not known - * @param[out] reserve_pub set to last reserve public key - * used for a wire transfer from the account to the - * exchange; alternatively used to authorize access, - * all zeros if not known - * @param[out] access_token set to the access token to begin - * work on KYC processes for this account - * @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 + * @param h_payto identifies account to look up requirement for + * @param[out] account_pub set to public key of the account + * needed to authorize access, all zeros if not known + * @param[out] reserve_pub set to last reserve public key + * used for a wire transfer from the account to the + * exchange; alternatively used to authorize access, + * all zeros if not known + * @param[out] access_token set to the access token to begin + * work on KYC processes for this account + * @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 (*lookup_kyc_requirement_by_row)( void *cls, - uint64_t requirement_row, + const struct TALER_PaytoHashP *h_payto, union TALER_AccountPublicKeyP *account_pub, struct TALER_ReservePublicKeyP *reserve_pub, struct TALER_AccountAccessTokenP *access_token, @@ -7022,6 +7064,23 @@ struct TALER_EXCHANGEDB_Plugin /** + * Lookup KYC rules by account access token. + * + * @param cls closure + * @param h_payto account payto hash to look under + * @param[out] jnew_rules set to active LegitimizationRuleSet + * @param[out] rowid row of the last legitimization outcome + * @return database transaction status + */ + enum GNUNET_DB_QueryStatus + (*lookup_rules_by_access_token)( + void *cls, + const struct TALER_PaytoHashP *h_payto, + json_t **jnew_rules, + uint64_t *rowid); + + + /** * Lookup KYC process meta data. * * @param cls closure @@ -7069,6 +7128,13 @@ struct TALER_EXCHANGEDB_Plugin * * @param cls the @e cls of this struct with the plugin-specific state * @param h_payto account identifier + * @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 @@ -7077,6 +7143,10 @@ struct TALER_EXCHANGEDB_Plugin (*get_kyc_rules)( void *cls, const struct TALER_PaytoHashP *h_payto, + bool *no_account_pub, + union TALER_AccountPublicKeyP *account_pub, + bool *no_reserve_pub, + struct TALER_ReservePublicKeyP *reserve_pub, json_t **jrules); @@ -7159,6 +7229,28 @@ struct TALER_EXCHANGEDB_Plugin /** + * 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 + (*select_deposit_amounts_for_kyc_check)( + void *cls, + const struct TALER_PaytoHashP *h_payto, + struct GNUNET_TIME_Absolute time_limit, + TALER_EXCHANGEDB_KycAmountCallback kac, + void *kac_cls); + + + /** * Store automated legitimization outcome. * * @param cls closure @@ -7440,11 +7532,6 @@ struct TALER_EXCHANGEDB_Plugin * 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 @@ -7454,6 +7541,40 @@ struct TALER_EXCHANGEDB_Plugin struct TALER_AccountAccessTokenP *access_token, struct TALER_PaytoHashP *h_payto, json_t **jmeasures, + bool *is_finished); + + + /** + * 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] 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 + (*lookup_completed_legitimization)( + void *cls, + uint64_t legitimization_measure_serial_id, + uint32_t measure_index, + struct TALER_AccountAccessTokenP *access_token, + struct TALER_PaytoHashP *h_payto, + json_t **jmeasures, bool *is_finished, size_t *encrypted_attributes_len, void **encrypted_attributes); @@ -7516,10 +7637,32 @@ struct TALER_EXCHANGEDB_Plugin /** + * 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 + (*insert_active_legitimization_measure) ( + void *cls, + const struct TALER_AccountAccessTokenP *access_token, + const json_t *jmeasures, + uint64_t *legitimization_measure_serial_id); + + + /** * 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 @@ -7541,6 +7684,7 @@ struct TALER_EXCHANGEDB_Plugin enum GNUNET_DB_QueryStatus (*insert_aml_decision)( void *cls, + const char *payto_uri, const struct TALER_PaytoHashP *h_payto, struct GNUNET_TIME_Timestamp decision_time, struct GNUNET_TIME_Timestamp expiration_time, diff --git a/src/include/taler_extensions.h b/src/include/taler_extensions.h index 1eb567f72..d924d1aba 100644 --- a/src/include/taler_extensions.h +++ b/src/include/taler_extensions.h @@ -88,7 +88,7 @@ struct TALER_Extension * The name of the extension, must be unique among all loaded extensions. It * is used in URLs for /extension/$NAME as well. */ - char *name; + const char *name; /** * Criticality of the extension. It has the same semantics as "critical" has @@ -103,7 +103,7 @@ struct TALER_Extension * Version of the extension must be provided in Taler's protocol version ranges notation, see * https://docs.taler.net/core/api-common.html#protocol-version-ranges */ - char *version; + const char *version; /** * If the extension is marked as enabled, it will be listed in the diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h index dd47feb12..0e8c8fc2b 100644 --- a/src/include/taler_json_lib.h +++ b/src/include/taler_json_lib.h @@ -151,7 +151,7 @@ TALER_JSON_pack_token_issue_sig ( struct GNUNET_JSON_PackSpec TALER_JSON_pack_token_envelope ( const char *name, - const struct TALER_TokenEnvelopeP *envelope); + const struct TALER_TokenEnvelope *envelope); /** @@ -209,6 +209,17 @@ TALER_JSON_pack_age_commitment ( /** + * Generate packer instruction of a KYC Trigger Event. + * + * @param name name of the field to add to the object + * @param event event type to add + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +TALER_JSON_pack_kycte (const char *name, + enum TALER_KYCLOGIC_KycTriggerEvent event); + +/** * Convert a TALER amount to a JSON object. * * @param amount the amount @@ -635,7 +646,7 @@ TALER_JSON_spec_blinded_token_issue_sig ( struct GNUNET_JSON_Specification TALER_JSON_spec_token_envelope ( const char *field, - struct TALER_TokenEnvelopeP *env); + struct TALER_TokenEnvelope *env); /** @@ -918,7 +929,7 @@ typedef void * @param cb function to call on the result * @param cb_cls closure for @a cb * @param binary name of the binary to execute - * @param ... NULL-terminated list of arguments for the @a binary, + * @param argv NULL-terminated list of arguments for the @a binary, * usually starting with again the name of the binary * @return handle to cancel the operation (and kill the helper) */ @@ -928,7 +939,7 @@ TALER_JSON_external_conversion_start ( TALER_JSON_JsonCallback cb, void *cb_cls, const char *binary, - ...); + const char **argv); /** * Abort external conversion, killing the process and preventing diff --git a/src/include/taler_kyclogic_lib.h b/src/include/taler_kyclogic_lib.h index 39256bb1e..098b9c7fe 100644 --- a/src/include/taler_kyclogic_lib.h +++ b/src/include/taler_kyclogic_lib.h @@ -54,7 +54,8 @@ enum TALER_KYCLOGIC_KycTriggerEvent TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE = 3, /** - * Wallet balance exceeds threshold. + * Wallet balance exceeds threshold. The timeframe is + * irrelevant for this limit. */ TALER_KYCLOGIC_KYC_TRIGGER_WALLET_BALANCE = 4, @@ -67,7 +68,19 @@ enum TALER_KYCLOGIC_KycTriggerEvent * Deposits have been aggregated, we are wiring a * certain amount into a (merchant) bank account. */ - TALER_KYCLOGIC_KYC_TRIGGER_AGGREGATE = 6 + TALER_KYCLOGIC_KYC_TRIGGER_AGGREGATE = 6, + + /** + * Limit per transaction. The timeframe is + * irrelevant for this limit. + */ + TALER_KYCLOGIC_KYC_TRIGGER_TRANSACTION = 7, + + /** + * Limit per refund. The timeframe is + * irrelevant for this limit. + */ + TALER_KYCLOGIC_KYC_TRIGGER_REFUND = 8 }; @@ -151,11 +164,6 @@ struct TALER_KYCLOGIC_KycCheck unsigned int num_outputs; /** - * True if clients can voluntarily trigger this check. - */ - bool voluntary; - - /** * Type of the KYC check. */ enum TALER_KYCLOGIC_CheckType type; @@ -225,16 +233,6 @@ TALER_KYCLOGIC_kyc_trigger_from_string ( /** - * Convert KYC trigger value to human-readable string. - * - * @param trigger value to convert - * @return human-readable representation of the @a trigger - */ -const char * -TALER_KYCLOGIC_kyc_trigger2s (enum TALER_KYCLOGIC_KycTriggerEvent trigger); - - -/** * Initialize KYC subsystem. Loads the KYC configuration. * * @param cfg configuration to parse @@ -356,6 +354,56 @@ TALER_KYCLOGIC_kyc_test_required ( /** + * Return JSON array of AccountLimit objects with hard limits of this exchange + * suitable for the "hard_limits" field of the "/keys" response. + * + * @return the JSON array of AccountLimit objects, + * empty array if there are no hard limits + */ +json_t * +TALER_KYCLOGIC_get_hard_limits (void); + + +/** + * Return JSON array of ZeroLimitedOperation objects with + * operations for which this exchange has a limit + * of zero, that means KYC is always required (or + * the operation is categorically forbidden). + * + * @return the JSON array of ZeroLimitedOperation objects, + * empty array if there are no hard limits + */ +json_t * +TALER_KYCLOGIC_get_zero_limits (void); + + +/** + * Obtain set of all measures that + * could be triggered at an amount of zero and that + * thus might be requested before a client even + * has performed any operation. + * + * @param lrs rule set to investigate, NULL for default + * @return LegitimizationMeasures, NULL on error + */ +json_t * +TALER_KYCLOGIC_zero_measures ( + const struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs); + + +/** + * Obtain set of all voluntary measures that + * could be triggered by clients at will. + * + * @param lrs rule set to investigate, NULL for default + * @return array of MeasureInformation, never NULL + */ +json_t * +TALER_KYCLOGIC_voluntary_measures ( + const struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs); + + +/** * Get human-readable name of KYC rule. * * @param r rule to convert @@ -522,6 +570,7 @@ TALER_KYCLOGIC_check_form ( * * @param check_name the prescribed check * @param prog_name the program to run + * @param context context to return, can be NULL * @param access_token access token for the measure * @param offset offset of the measure * @param legitimization_measure_row_id row in the legitimization_measures table @@ -531,23 +580,24 @@ json_t * TALER_KYCLOGIC_measure_to_requirement ( const char *check_name, const char *prog_name, + const json_t *context, const struct TALER_AccountAccessTokenP *access_token, size_t offset, uint64_t legitimization_measure_row_id); /** - * Lookup @a measure_name in @a lrs and create JSON - * object with the corresponding LegitimizationMeasures. + * Lookup measures from @a measures_spec in @a lrs and create JSON object with + * the corresponding LegitimizationMeasures. * * @param lrs set of legitimization rules - * @param measure_name name of a measure to trigger from @a lrs + * @param measures_spec space-separated set of a measures to trigger from @a lrs; "+"-prefixed if AND-cominbation applies * @return JSON object of type LegitimizationMeasures */ json_t * -TALER_KYCLOGIC_get_measure ( +TALER_KYCLOGIC_get_measures ( const struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs, - const char *measure_name); + const char *measures_spec); /** * Lookup the provider for the given @a check_name. @@ -722,6 +772,22 @@ TALER_KYCLOGIC_rule_get_instant_measure ( /** + * Check if there is a measure in @a lrs + * that is included in @a measure_spec + * and a SKIP measure, and thus should be immediately + * executed. + * + * @param rls legitimization rule set + * @param measures_spec measures spec + * @returns NULL if there is no instant measure + */ +const struct TALER_KYCLOGIC_Measure * +TALER_KYCLOGIC_get_instant_measure ( + const struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs, + const char *measures_spec); + + +/** * Handle to manage a running AML program. */ struct TALER_KYCLOGIC_AmlProgramRunnerHandle; diff --git a/src/include/taler_pq_lib.h b/src/include/taler_pq_lib.h index f45de61d9..e9929a0e9 100644 --- a/src/include/taler_pq_lib.h +++ b/src/include/taler_pq_lib.h @@ -169,10 +169,11 @@ TALER_PQ_query_param_array_blinded_coin_hash ( /** - * Generate query parameter for an array of GNUNET_HashCode + * Generate query parameter for an array of + * `struct GNUNET_HashCode`. * * @param num number of elements in @e hash_codes - * @param hashes array of GNUNET_HashCode + * @param hashes array of hashes * @param db context for the db-connection */ struct GNUNET_PQ_QueryParam @@ -183,6 +184,21 @@ TALER_PQ_query_param_array_hash_code ( /** + * Generate query parameter for an array of + * `struct TALER_DenominationHashP` + * + * @param num number of elements in @e hash_codes + * @param denom_hs array of denomination hashes to encode + * @param db context for the db-connection + */ +struct GNUNET_PQ_QueryParam +TALER_PQ_query_param_array_denom_hash ( + size_t num, + const struct TALER_DenominationHashP *denom_hs, + struct GNUNET_PQ_Context *db); + + +/** * Generate query parameter for an array of amounts * * @param num of elements in @e amounts diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h index b87b9d95b..6b7ae667d 100644 --- a/src/include/taler_testing_lib.h +++ b/src/include/taler_testing_lib.h @@ -315,10 +315,10 @@ struct TALER_TESTING_Command * @return #GNUNET_OK on success */ enum GNUNET_GenericReturnValue - (*traits)(void *cls, - const void **ret, - const char *trait, - unsigned int index); + (*traits)(void *cls, + const void **ret, + const char *trait, + unsigned int index); /** * When did the execution of this command start? @@ -354,8 +354,9 @@ struct TALER_TESTING_Command * @return the command, if it is found, or NULL. */ const struct TALER_TESTING_Command * -TALER_TESTING_interpreter_lookup_command (struct TALER_TESTING_Interpreter *is, - const char *label); +TALER_TESTING_interpreter_lookup_command ( + struct TALER_TESTING_Interpreter *is, + const char *label); /** @@ -366,8 +367,9 @@ TALER_TESTING_interpreter_lookup_command (struct TALER_TESTING_Interpreter *is, * @return the command, if it is found, or NULL. */ const struct TALER_TESTING_Command * -TALER_TESTING_interpreter_get_command (struct TALER_TESTING_Interpreter *is, - const char *name); +TALER_TESTING_interpreter_get_command ( + struct TALER_TESTING_Interpreter *is, + const char *name); /** @@ -627,6 +629,19 @@ TALER_TESTING_cmd_set_var (const char *name, /** + * Update interpeter @a is variable state due to execution of @a cmd. + * + * @param[in,out] is interpreter to update + * @param[in,out] cmd command that we are exeucting and that + * needs to be checked for side-effects on the variable state + */ +void +TALER_TESTING_update_variables_ ( + struct TALER_TESTING_Interpreter *is, + struct TALER_TESTING_Command *cmd); + + +/** * Launch GNU Taler setup. * * @param label command label. @@ -1658,11 +1673,12 @@ TALER_TESTING_cmd_track_transfer (const char *label, * @return the command */ struct TALER_TESTING_Command -TALER_TESTING_cmd_check_bank_transfer (const char *label, - const char *exchange_base_url, - const char *amount, - const char *debit_payto, - const char *credit_payto); +TALER_TESTING_cmd_check_bank_transfer ( + const char *label, + const char *exchange_base_url, + const char *amount, + const char *debit_payto, + const char *credit_payto); /** @@ -1677,11 +1693,12 @@ TALER_TESTING_cmd_check_bank_transfer (const char *label, * @return the command */ struct TALER_TESTING_Command -TALER_TESTING_cmd_check_bank_admin_transfer (const char *label, - const char *amount, - const char *debit_payto, - const char *credit_payto, - const char *reserve_pub_ref); +TALER_TESTING_cmd_check_bank_admin_transfer ( + const char *label, + const char *amount, + const char *debit_payto, + const char *credit_payto, + const char *reserve_pub_ref); /** @@ -1696,8 +1713,9 @@ TALER_TESTING_cmd_check_bank_admin_transfer (const char *label, * @return the command. */ struct TALER_TESTING_Command -TALER_TESTING_cmd_check_bank_transfer_with_ref (const char *label, - const char *deposit_reference); +TALER_TESTING_cmd_check_bank_transfer_with_ref ( + const char *label, + const char *deposit_reference); /** @@ -2209,6 +2227,7 @@ TALER_TESTING_cmd_wallet_kyc_get ( * @param label command label. * @param payment_target_reference command with a payment target to query * @param account_reference command with account private key to query + * @param lpt target for long polling * @param expected_response_code expected HTTP status * @return the command */ @@ -2217,6 +2236,7 @@ TALER_TESTING_cmd_check_kyc_get ( const char *label, const char *payment_target_reference, const char *account_reference, + enum TALER_EXCHANGE_KycLongPollTarget lpt, unsigned int expected_response_code); @@ -2636,7 +2656,7 @@ TALER_TESTING_get_trait (const struct TALER_TESTING_Trait *traits, enum GNUNET_GenericReturnValue \ TALER_TESTING_get_trait_ ## name ( \ const struct TALER_TESTING_Command *cmd, \ - type **ret); \ + type * *ret); \ struct TALER_TESTING_Trait \ TALER_TESTING_make_trait_ ## name ( \ type * value); @@ -2679,11 +2699,11 @@ TALER_TESTING_get_trait (const struct TALER_TESTING_Trait *traits, TALER_TESTING_get_trait_ ## name ( \ const struct TALER_TESTING_Command *cmd, \ unsigned int index, \ - type **ret); \ + type * *ret); \ struct TALER_TESTING_Trait \ TALER_TESTING_make_trait_ ## name ( \ unsigned int index, \ - type *value); + type * value); /** diff --git a/src/include/taler_twister_testing_lib.h b/src/include/taler_twister_testing_lib.h index cdafab04b..711d6b652 100644 --- a/src/include/taler_twister_testing_lib.h +++ b/src/include/taler_twister_testing_lib.h @@ -29,7 +29,29 @@ #include "taler_testing_lib.h" #define TWISTER_FAIL() \ - do {GNUNET_break (0); return NULL; } while (0) + do {GNUNET_break (0); return NULL; } while (0) + + +/** + * Prepare twister for execution; mainly checks whether the + * HTTP port is available and construct the base URL based on it. + * + * @param config_filename configuration file name. + * @return twister base URL, NULL upon errors. + */ +char * +TALER_TWISTER_prepare_twister (const char *config_filename); + + +/** + * Run the twister service. + * + * @param config_filename configuration file name. + * @return twister process handle, NULL upon errors. + */ +struct GNUNET_OS_Process * +TALER_TWISTER_run_twister (const char *config_filename); + /** * Define a "hack response code" CMD. This causes the next diff --git a/src/include/taler_util.h b/src/include/taler_util.h index f2121f9cb..e8e8610b5 100644 --- a/src/include/taler_util.h +++ b/src/include/taler_util.h @@ -32,11 +32,18 @@ #include "taler_amount_lib.h" #include "taler_crypto_lib.h" +#if MHD_VERSION < 0x00097701 +#define MHD_create_response_from_buffer_static(s, b) \ + MHD_create_response_from_buffer (s, \ + (const char *) b, \ + MHD_RESPMEM_PERSISTENT) +#endif + /** * Version of the Taler API, in hex. * Thus 0.8.4-1 = 0x00080401. */ -#define TALER_API_VERSION 0x00090401 +#define TALER_API_VERSION 0x000D0000 /** * Stringify operator. @@ -57,16 +64,16 @@ /* Define logging functions */ #define TALER_LOG_DEBUG(...) \ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) #define TALER_LOG_INFO(...) \ - GNUNET_log (GNUNET_ERROR_TYPE_INFO, __VA_ARGS__) + GNUNET_log (GNUNET_ERROR_TYPE_INFO, __VA_ARGS__) #define TALER_LOG_WARNING(...) \ - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, __VA_ARGS__) + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, __VA_ARGS__) #define TALER_LOG_ERROR(...) \ - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, __VA_ARGS__) + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, __VA_ARGS__) /** @@ -77,11 +84,11 @@ * @param reason string to print as warning */ #define TALER_assert_as(EXP, reason) \ - do { \ - if (EXP) break; \ - TALER_LOG_ERROR ("%s at %s:%d\n", reason, __FILE__, __LINE__); \ - abort (); \ - } while (0) + do { \ + if (EXP) break; \ + TALER_LOG_ERROR ("%s at %s:%d\n", reason, __FILE__, __LINE__); \ + abort (); \ + } while (0) /** @@ -112,11 +119,11 @@ #define TALER_gcry_ok(cmd) \ - do {int rc; rc = cmd; if (! rc) break; \ - TALER_LOG_ERROR ("A Gcrypt call failed at %s:%d with error: %s\n", \ - __FILE__, \ - __LINE__, gcry_strerror (rc)); abort (); } while (0 \ - ) + do {int rc; rc = cmd; if (! rc) break; \ + TALER_LOG_ERROR ("A Gcrypt call failed at %s:%d with error: %s\n", \ + __FILE__, \ + __LINE__, gcry_strerror (rc)); abort (); } while (0 \ + ) /** @@ -590,6 +597,66 @@ TALER_iban_validate (const char *iban); /** + * Possible choices for long-polling for the deposit status. + */ +enum TALER_DepositGetLongPollTarget +{ + /** + * No long-polling. + */ + TALER_DGLPT_NONE = 0, + + /** + * Wait for KYC required/ACCEPTED state *or* for + * OK state. + */ + TALER_DGLPT_KYC_REQUIRED_OR_OK = 1, + + /** + * Wait for the OK-state only. + */ + TALER_DGLPT_OK = 2, + + /** + * Maximum allowed value. + */ + TALER_DGLPT_MAX = 2 +}; + + +/** + * Possible choices for long-polling for the KYC status. + */ +enum TALER_EXCHANGE_KycLongPollTarget +{ + /** + * No long polling. + */ + TALER_EXCHANGE_KLPT_NONE = 0, + + /** + * Wait for KYC auth transfer to be complete. + */ + TALER_EXCHANGE_KLPT_KYC_AUTH_TRANSFER = 1, + + /** + * Wait for AML investigation to be complete. + */ + TALER_EXCHANGE_KLPT_INVESTIGATION_DONE = 2, + + /** + * Wait for KYC status to be OK. + */ + TALER_EXCHANGE_KLPT_KYC_OK = 3, + + /** + * Maximum legal value in this enumeration. + */ + TALER_EXCHANGE_KLPT_MAX = 3 +}; + + +/** * Possible values for a binary filter. */ enum TALER_EXCHANGE_YesNoAll @@ -776,7 +843,7 @@ TALER_get_lowest_age ( * @return lowest age for the largest age group */ #define TALER_adult_age(mask) \ - sizeof((mask)->bits) * 8 - __builtin_clz ((mask)->bits) - 1 + sizeof((mask)->bits) * 8 - __builtin_clz ((mask)->bits) - 1 #undef __TALER_UTIL_LIB_H_INSIDE__ diff --git a/src/json/conversion.c b/src/json/conversion.c index 42b6f8ed2..b319eae0b 100644 --- a/src/json/conversion.c +++ b/src/json/conversion.c @@ -298,12 +298,11 @@ TALER_JSON_external_conversion_start (const json_t *input, TALER_JSON_JsonCallback cb, void *cb_cls, const char *binary, - ...) + const char **argv) { struct TALER_JSON_ExternalConversion *ec; struct GNUNET_DISK_PipeHandle *pipe_stdin; struct GNUNET_DISK_PipeHandle *pipe_stdout; - va_list ap; ec = GNUNET_new (struct TALER_JSON_ExternalConversion); ec->cb = cb; @@ -312,15 +311,12 @@ TALER_JSON_external_conversion_start (const json_t *input, GNUNET_assert (NULL != pipe_stdin); pipe_stdout = GNUNET_DISK_pipe (GNUNET_DISK_PF_BLOCKING_WRITE); GNUNET_assert (NULL != pipe_stdout); - va_start (ap, - binary); - ec->helper = GNUNET_OS_start_process_va (GNUNET_OS_INHERIT_STD_ERR, - pipe_stdin, - pipe_stdout, - NULL, - binary, - ap); - va_end (ap); + ec->helper = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_ERR, + pipe_stdin, + pipe_stdout, + NULL, + binary, + (char *const *) argv); if (NULL == ec->helper) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -345,6 +341,9 @@ TALER_JSON_external_conversion_start (const json_t *input, GNUNET_DISK_pipe_close (pipe_stdout)); ec->write_buf = json_dumps (input, JSON_COMPACT); ec->write_size = strlen (ec->write_buf); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Passing %llu bytes to JSON conversion tool\n", + (unsigned long long) ec->write_size); ec->read_task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, ec->chld_stdout, diff --git a/src/json/json.c b/src/json/json.c index 639bd530c..551605cb9 100644 --- a/src/json/json.c +++ b/src/json/json.c @@ -701,6 +701,8 @@ parse_path (json_t *obj, { char *end_bracket = strchr (bracket, ']'); + json_t *array; + if (NULL == end_bracket) { GNUNET_free (id); @@ -708,12 +710,10 @@ parse_path (json_t *obj, return GNUNET_SYSERR; } *end_bracket = '\0'; - *bracket = '\0'; bracket++; - - json_t *array = json_object_get (obj, - next_id); + array = json_object_get (obj, + next_id); if (0 == strcmp (bracket, "*")) { @@ -808,7 +808,7 @@ TALER_JSON_get_error_code (const json_t *json) return TALER_EC_INVALID; } if (json_is_integer (jc)) - return (enum TALER_ErrorCode) json_integer_value (jc); + return (enum TALER_ErrorCode) (int) json_integer_value (jc); GNUNET_break_op (0); return TALER_EC_INVALID; } diff --git a/src/json/json_helper.c b/src/json/json_helper.c index 82cc13413..2d1037ef6 100644 --- a/src/json/json_helper.c +++ b/src/json/json_helper.c @@ -555,7 +555,7 @@ TALER_JSON_spec_blinded_token_issue_sig ( struct GNUNET_JSON_Specification TALER_JSON_spec_token_envelope (const char *field, - struct TALER_TokenEnvelopeP *env) + struct TALER_TokenEnvelope *env) { env->blinded_pub = NULL; return GNUNET_JSON_spec_blinded_message (field, @@ -1475,6 +1475,10 @@ parse_kycte (void *cls, .val = TALER_KYCLOGIC_KYC_TRIGGER_RESERVE_CLOSE }, { .name = "AGGREGATE", .val = TALER_KYCLOGIC_KYC_TRIGGER_AGGREGATE }, + { .name = "TRANSACTION", + .val = TALER_KYCLOGIC_KYC_TRIGGER_TRANSACTION }, + { .name = "REFUND", + .val = TALER_KYCLOGIC_KYC_TRIGGER_REFUND }, { .name = NULL, .val = TALER_KYCLOGIC_KYC_TRIGGER_NONE }, }; diff --git a/src/json/json_pack.c b/src/json/json_pack.c index 82eb91cc8..859976acb 100644 --- a/src/json/json_pack.c +++ b/src/json/json_pack.c @@ -97,6 +97,47 @@ TALER_JSON_pack_age_commitment ( struct GNUNET_JSON_PackSpec +TALER_JSON_pack_kycte (const char *name, + enum TALER_KYCLOGIC_KycTriggerEvent event) +{ + const char *str = "INVALID"; + + switch (event) + { + case TALER_KYCLOGIC_KYC_TRIGGER_NONE: + str = "NONE"; + break; + case TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW: + str = "WITHDRAW"; + break; + case TALER_KYCLOGIC_KYC_TRIGGER_DEPOSIT: + str = "DEPOSIT"; + break; + case TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE: + str = "MERGE"; + break; + case TALER_KYCLOGIC_KYC_TRIGGER_WALLET_BALANCE: + str = "BALANCE"; + break; + case TALER_KYCLOGIC_KYC_TRIGGER_RESERVE_CLOSE: + str = "CLOSE"; + break; + case TALER_KYCLOGIC_KYC_TRIGGER_AGGREGATE: + str = "AGGREGATE"; + break; + case TALER_KYCLOGIC_KYC_TRIGGER_TRANSACTION: + str = "TRANSACTION"; + break; + case TALER_KYCLOGIC_KYC_TRIGGER_REFUND: + str = "REFUND"; + break; + } + return GNUNET_JSON_pack_string (name, + str); +} + + +struct GNUNET_JSON_PackSpec TALER_JSON_pack_denom_pub ( const char *name, const struct TALER_DenominationPublicKey *pk) @@ -173,7 +214,7 @@ TALER_JSON_pack_token_issue_sig ( struct GNUNET_JSON_PackSpec TALER_JSON_pack_token_envelope ( const char *name, - const struct TALER_TokenEnvelopeP *envelope) + const struct TALER_TokenEnvelope *envelope) { struct GNUNET_JSON_PackSpec ps = { .field_name = name, diff --git a/src/json/test_conversion.c b/src/json/test_conversion.c index 449b02d59..e28e8be66 100644 --- a/src/json/test_conversion.c +++ b/src/json/test_conversion.c @@ -65,6 +65,7 @@ conv_cb (void *cls, GNUNET_JSON_pack_string ("foo", "arg") ); + GNUNET_assert (NULL != expect); if (1 == json_equal (expect, result)) { @@ -119,6 +120,7 @@ run (void *cls) GNUNET_JSON_pack_string ("key", "foo") ); + GNUNET_assert (NULL != input); ec = TALER_JSON_external_conversion_start (input, &conv_cb, NULL, @@ -140,7 +142,7 @@ main (int argc, unsetenv ("XDG_DATA_HOME"); unsetenv ("XDG_CONFIG_HOME"); GNUNET_log_setup ("test-conversion", - "WARNING", + "INFO", NULL); GNUNET_OS_init (TALER_project_data_default ()); global_ret = 1; diff --git a/src/json/test_json.c b/src/json/test_json.c index fba72f84b..4dac3bf79 100644 --- a/src/json/test_json.c +++ b/src/json/test_json.c @@ -76,9 +76,11 @@ path_cb (void *cls, json_t *parent) { struct TestPath_Closure *cmp = cls; + unsigned int i; + if (NULL == cmp) return; - unsigned int i = cmp->results_length; + i = cmp->results_length; if ((0 != strcmp (cmp->object_ids[i], object_id)) || (1 != json_equal (cmp->parents[i], diff --git a/src/kyclogic/Makefile.am b/src/kyclogic/Makefile.am index 7da1f758f..35e68e1a2 100644 --- a/src/kyclogic/Makefile.am +++ b/src/kyclogic/Makefile.am @@ -41,7 +41,7 @@ libtalerkyclogic_la_LIBADD = \ -lgnunetutil \ $(XLIB) libtalerkyclogic_la_LDFLAGS = \ - -version-info 0:0:0 \ + -version-info 1:0:0 \ -no-undefined diff --git a/src/kyclogic/kyclogic-kycaid.conf b/src/kyclogic/kyclogic-kycaid.conf index 6db48083e..925b565c0 100644 --- a/src/kyclogic/kyclogic-kycaid.conf +++ b/src/kyclogic/kyclogic-kycaid.conf @@ -9,10 +9,6 @@ LOGIC = kycaid USER_TYPE = INDIVIDUAL PROVIDED_CHECKS = EXAMPLE_DO_NOT_USE -# Generic converter that does nothing. -CONVERTER = cat - - # How long is the KYC check valid? KYC_KYCAID_VALIDITY = forever diff --git a/src/kyclogic/kyclogic-oauth2.conf b/src/kyclogic/kyclogic-oauth2.conf index 2f78818a2..af9a70ec4 100644 --- a/src/kyclogic/kyclogic-oauth2.conf +++ b/src/kyclogic/kyclogic-oauth2.conf @@ -9,9 +9,6 @@ LOGIC = oauth2 USER_TYPE = INDIVIDUAL PROVIDED_CHECKS = EXAMPLE_DO_NOT_USE -# Generic converter. -CONVERTER = cat - # Converter that converts OAuth2.0 data about the user # into GNU Taler standardized attribute data. # diff --git a/src/kyclogic/kyclogic_api.c b/src/kyclogic/kyclogic_api.c index 7503721cb..910f98c62 100644 --- a/src/kyclogic/kyclogic_api.c +++ b/src/kyclogic/kyclogic_api.c @@ -40,12 +40,6 @@ struct TALER_KYCLOGIC_KycProvider char *provider_name; /** - * Name of a program to run to convert output of the - * plugin into the desired set of attributes. - */ - char *converter_name; - - /** * Logic to run for this provider. */ struct TALER_KYCLOGIC_Plugin *logic; @@ -155,6 +149,10 @@ struct TALER_KYCLOGIC_Measure */ json_t *context; + /** + * Can this measure be triggered voluntarily? + */ + bool voluntary; }; @@ -333,8 +331,8 @@ find_check (const char *check_name) struct TALER_KYCLOGIC_KycCheck *kyc_check = kyc_checks[i]; - if (0 == strcmp (check_name, - kyc_check->check_name)) + if (0 == strcasecmp (check_name, + kyc_check->check_name)) return kyc_check; } GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -358,8 +356,8 @@ find_program (const char *program_name) struct TALER_KYCLOGIC_AmlProgram *program = aml_programs[i]; - if (0 == strcmp (program_name, - program->program_name)) + if (0 == strcasecmp (program_name, + program->program_name)) return program; } GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -383,8 +381,8 @@ find_provider (const char *provider_name) struct TALER_KYCLOGIC_KycProvider *provider = kyc_providers[i]; - if (0 == strcmp (provider_name, - provider->provider_name)) + if (0 == strcasecmp (provider_name, + provider->provider_name)) return provider; } GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -495,7 +493,7 @@ TALER_KYCLOGIC_rules_parse (const json_t *jlrs) struct GNUNET_TIME_Timestamp expiration_time; const char *successor_measure = NULL; const json_t *jrules; - const json_t *jcustom_measures = NULL; + const json_t *jcustom_measures; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_timestamp ( "expiration_time", @@ -507,10 +505,8 @@ TALER_KYCLOGIC_rules_parse (const json_t *jlrs) NULL), GNUNET_JSON_spec_array_const ("rules", &jrules), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_object_const ("custom_measures", - &jcustom_measures), - NULL), + GNUNET_JSON_spec_object_const ("custom_measures", + &jcustom_measures), GNUNET_JSON_spec_end () }; struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs; @@ -603,6 +599,11 @@ TALER_KYCLOGIC_rules_parse (const json_t *jlrs) GNUNET_break_op (0); goto cleanup; } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Parsed KYC rule %u for %d with threshold %s\n", + (unsigned int) off, + (int) rule->trigger, + TALER_amount2s (&rule->threshold)); rule->lrs = lrs; rule->num_measures = json_array_size (jmeasures); rule->next_measures @@ -630,7 +631,8 @@ TALER_KYCLOGIC_rules_parse (const json_t *jlrs) GNUNET_break (0); goto cleanup; } - rule->next_measures[j] = GNUNET_strdup (str); + rule->next_measures[j] + = GNUNET_strdup (str); } } } @@ -652,6 +654,7 @@ TALER_KYCLOGIC_rules_parse (const json_t *jlrs) const char *check_name; const char *prog_name; const json_t *context = NULL; + bool voluntary = false; struct TALER_KYCLOGIC_Measure *measure = &lrs->custom_measures[off++]; struct GNUNET_JSON_Specification ispec[] = { @@ -660,8 +663,12 @@ TALER_KYCLOGIC_rules_parse (const json_t *jlrs) GNUNET_JSON_spec_string ("prog_name", &prog_name), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_array_const ("context", - &context), + GNUNET_JSON_spec_object_const ("context", + &context), + NULL), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_bool ("voluntary", + &voluntary), NULL), GNUNET_JSON_spec_end () }; @@ -680,6 +687,8 @@ TALER_KYCLOGIC_rules_parse (const json_t *jlrs) = GNUNET_strdup (check_name); measure->prog_name = GNUNET_strdup (prog_name); + measure->voluntary + = voluntary; if (NULL != context) measure->context = json_incref ((json_t*) context); @@ -774,84 +783,122 @@ TALER_KYCLOGIC_status2s (enum TALER_KYCLOGIC_KycStatus status) json_t * TALER_KYCLOGIC_rules_to_limits (const json_t *jrules) { - json_t *limits; - json_t *limit; - json_t *rule; - size_t idx; + if (NULL == jrules) + { + /* default limits apply */ + const struct TALER_KYCLOGIC_KycRule *rules + = default_rules.kyc_rules; + unsigned int num_rules + = default_rules.num_kyc_rules; + json_t *jlimits; + + jlimits = json_array (); + GNUNET_assert (NULL != jlimits); + for (unsigned int i = 0; i<num_rules; i++) + { + const struct TALER_KYCLOGIC_KycRule *rule = &rules[i]; + json_t *limit; + + if (! rule->exposed) + continue; + limit = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_bool ("soft_limit", + ! rule->verboten), + TALER_JSON_pack_kycte ("operation_type", + rule->trigger), + GNUNET_JSON_pack_time_rel ("timeframe", + rule->timeframe), + TALER_JSON_pack_amount ("threshold", + &rule->threshold) + ); + GNUNET_assert (0 == + json_array_append_new (jlimits, + limit)); + } + return jlimits; + } - limits = json_array (); - GNUNET_assert (NULL != limits); - json_array_foreach ((json_t *) jrules, idx, rule) { - struct GNUNET_TIME_Relative timeframe; - struct TALER_Amount threshold; - bool exposed = false; - const json_t *jmeasures; - enum TALER_KYCLOGIC_KycTriggerEvent operation_type; - struct GNUNET_JSON_Specification spec[] = { - TALER_JSON_spec_kycte ("operation_type", - &operation_type), - GNUNET_JSON_spec_relative_time ("timeframe", - &timeframe), - TALER_JSON_spec_amount_any ("threshold", - &threshold), - GNUNET_JSON_spec_array_const ("measures", - &jmeasures), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_bool ("exposed", - &exposed), - NULL), - GNUNET_JSON_spec_end () - }; - bool forbidden = false; - size_t i; - json_t *jmeasure; + json_t *limits; + json_t *limit; + json_t *rule; + size_t idx; - if (GNUNET_OK != - GNUNET_JSON_parse (jrules, - spec, - NULL, NULL)) + limits = json_array (); + GNUNET_assert (NULL != limits); + json_array_foreach ((json_t *) jrules, idx, rule) { - GNUNET_break_op (0); - json_decref (limits); - return NULL; - } - if (! exposed) - continue; - json_array_foreach (jmeasures, i, jmeasure) - { - const char *val; + struct GNUNET_TIME_Relative timeframe; + struct TALER_Amount threshold; + bool exposed = false; + const json_t *jmeasures; + enum TALER_KYCLOGIC_KycTriggerEvent operation_type; + struct GNUNET_JSON_Specification spec[] = { + TALER_JSON_spec_kycte ("operation_type", + &operation_type), + GNUNET_JSON_spec_relative_time ("timeframe", + &timeframe), + TALER_JSON_spec_amount_any ("threshold", + &threshold), + GNUNET_JSON_spec_array_const ("measures", + &jmeasures), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_bool ("exposed", + &exposed), + NULL), + GNUNET_JSON_spec_end () + }; + bool forbidden = false; + size_t i; + json_t *jmeasure; - val = json_string_value (jmeasure); - if (NULL == val) + if (GNUNET_OK != + GNUNET_JSON_parse (jrules, + spec, + NULL, NULL)) { GNUNET_break_op (0); json_decref (limits); return NULL; } - if (0 == strcmp (KYC_MEASURE_IMPOSSIBLE, - val)) - forbidden = true; - } - - limit = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ( - "operation_type", - TALER_KYCLOGIC_kyc_trigger2s (operation_type)), - GNUNET_JSON_pack_time_rel ( - "timeframe", - timeframe), - TALER_JSON_pack_amount ( - "threshold", - &threshold), - GNUNET_JSON_pack_bool ( - "soft_limit", - ! forbidden)); - GNUNET_assert (0 == - json_array_append_new (limits, - limit)); + if (! exposed) + continue; + json_array_foreach (jmeasures, i, jmeasure) + { + const char *val; + + val = json_string_value (jmeasure); + if (NULL == val) + { + GNUNET_break_op (0); + json_decref (limits); + return NULL; + } + if (0 == strcasecmp (KYC_MEASURE_IMPOSSIBLE, + val)) + forbidden = true; + } + + limit = GNUNET_JSON_PACK ( + TALER_JSON_pack_kycte ( + "operation_type", + operation_type), + GNUNET_JSON_pack_time_rel ( + "timeframe", + timeframe), + TALER_JSON_pack_amount ( + "threshold", + &threshold), + /* optional since v21, defaults to 'false' */ + GNUNET_JSON_pack_bool ( + "soft_limit", + ! forbidden)); + GNUNET_assert (0 == + json_array_append_new (limits, + limit)); + } + return limits; } - return limits; } @@ -864,7 +911,7 @@ TALER_KYCLOGIC_rules_to_limits (const json_t *jrules) * @param measure_name name of measure to find * @return NULL if not found, otherwise the measure */ -const struct TALER_KYCLOGIC_Measure * +static const struct TALER_KYCLOGIC_Measure * find_measure ( const struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs, const char *measure_name) @@ -876,8 +923,8 @@ find_measure ( const struct TALER_KYCLOGIC_Measure *cm = &lrs->custom_measures[i]; - if (0 == strcmp (measure_name, - cm->measure_name)) + if (0 == strcasecmp (measure_name, + cm->measure_name)) return cm; } } @@ -889,8 +936,8 @@ find_measure ( const struct TALER_KYCLOGIC_Measure *cm = &default_rules.custom_measures[i]; - if (0 == strcmp (measure_name, - cm->measure_name)) + if (0 == strcasecmp (measure_name, + cm->measure_name)) return cm; } } @@ -981,35 +1028,105 @@ TALER_KYCLOGIC_rule_to_measures ( json_t * -TALER_KYCLOGIC_get_measure ( - const struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs, - const char *measure_name) +TALER_KYCLOGIC_zero_measures ( + const struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs) { - const struct TALER_KYCLOGIC_Measure *ms; - json_t *mi; - json_t *jmeasures; + json_t *zero_measures; + const struct TALER_KYCLOGIC_KycRule *rules; + unsigned int num_rules; - if (0 == strcmp ("verboten", - measure_name)) - { - jmeasures = json_array (); - GNUNET_assert (NULL != jmeasures); - return GNUNET_JSON_PACK ( - GNUNET_JSON_pack_array_steal ("measures", - jmeasures), - GNUNET_JSON_pack_bool ("is_and_combinator", - false), - GNUNET_JSON_pack_bool ("verboten", - true)); - } - ms = find_measure (lrs, - measure_name); - if (NULL == ms) + if (NULL == lrs) + lrs = &default_rules; + rules = lrs->kyc_rules; + num_rules = lrs->num_kyc_rules; + zero_measures = json_array (); + GNUNET_assert (NULL != zero_measures); + for (unsigned int i = 0; i<num_rules; i++) { - GNUNET_break (0); - return NULL; + const struct TALER_KYCLOGIC_KycRule *rule = &rules[i]; + + if (! rule->exposed) + continue; + if (rule->verboten) + continue; /* see: hard_limits */ + if (! TALER_amount_is_zero (&rule->threshold)) + continue; + for (unsigned int j = 0; j<rule->num_measures; j++) + { + const struct TALER_KYCLOGIC_Measure *ms; + json_t *mi; + + ms = find_measure (lrs, + rule->next_measures[j]); + if (NULL == ms) + { + GNUNET_break (0); + json_decref (zero_measures); + return NULL; + } + if (0 == strcasecmp ("verboten", + ms->check_name)) + continue; /* not a measure to be selected */ + mi = GNUNET_JSON_PACK ( + TALER_JSON_pack_kycte ("operation_type", + rule->trigger), + GNUNET_JSON_pack_string ("check_name", + ms->check_name), + GNUNET_JSON_pack_string ("prog_name", + ms->prog_name), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_object_incref ("context", + ms->context))); + GNUNET_assert (0 == + json_array_append_new (zero_measures, + mi)); + } } - mi = GNUNET_JSON_PACK ( + return GNUNET_JSON_PACK ( + GNUNET_JSON_pack_array_steal ("measures", + zero_measures), + /* Zero-measures are always OR */ + GNUNET_JSON_pack_bool ("is_and_combinator", + false), + /* OR means verboten measures do not matter */ + GNUNET_JSON_pack_bool ("verboten", + false)); +} + + +/** + * Check if @a ms is a voluntary measure, and if so + * convert to JSON and append to @a voluntary_measures. + * + * @param[in,out] voluntary_measures JSON array of MeasureInformation + * @param ms a measure to possibly append + */ +static void +append_voluntary_measure ( + json_t *voluntary_measures, + const struct TALER_KYCLOGIC_Measure *ms) +{ +#if 0 + json_t *mj; +#endif + + if (! ms->voluntary) + return; + if (0 == strcasecmp ("verboten", + ms->check_name)) + return; /* very strange configuration */ +#if 0 + /* TODO: support vATTEST-9048 (this API in kyclogic!) */ + // NOTE: need to convert ms to "KycRequirementInformation" + // *and* in particular generate "id" values that + // are then understood to refer to the voluntary measures + // by the rest of the API (which is the hard part!) + // => need to change the API to encode the + // legitimization_outcomes row ID of the lrs from + // which the voluntary 'ms' originated, and + // then update the kyc-upload/kyc-start endpoints + // to recognize the new ID format! + mj = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("check_name", ms->check_name), GNUNET_JSON_pack_string ("prog_name", @@ -1017,18 +1134,166 @@ TALER_KYCLOGIC_get_measure ( GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_object_incref ("context", ms->context))); + GNUNET_assert (0 == + json_array_append_new (voluntary_measures, + mj)); +#endif +} + + +json_t * +TALER_KYCLOGIC_voluntary_measures ( + const struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs) +{ + json_t *voluntary_measures; + + voluntary_measures = json_array (); + GNUNET_assert (NULL != voluntary_measures); + if (NULL != lrs) + { + for (unsigned int i = 0; i<lrs->num_custom_measures; i++) + { + const struct TALER_KYCLOGIC_Measure *ms + = &lrs->custom_measures[i]; + + append_voluntary_measure (voluntary_measures, + ms); + } + } + for (unsigned int i = 0; i<default_rules.num_custom_measures; i++) + { + const struct TALER_KYCLOGIC_Measure *ms + = &default_rules.custom_measures[i]; + + append_voluntary_measure (voluntary_measures, + ms); + } + return voluntary_measures; +} + + +const struct TALER_KYCLOGIC_Measure * +TALER_KYCLOGIC_get_instant_measure ( + const struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs, + const char *measures_spec) +{ + char *nm; + const struct TALER_KYCLOGIC_Measure *ret = NULL; + + GNUNET_assert (NULL != measures_spec); + + if ('+' == measures_spec[0]) + { + nm = GNUNET_strdup (&measures_spec[1]); + } + else + { + nm = GNUNET_strdup (measures_spec); + } + for (const char *tok = strtok (nm, " "); + NULL != tok; + tok = strtok (NULL, " ")) + { + const struct TALER_KYCLOGIC_Measure *ms; + + if (0 == strcasecmp ("verboten", + tok)) + { + continue; + } + ms = find_measure (lrs, + tok); + if (NULL == ms) + { + GNUNET_break (0); + continue; + } + if (0 == strcasecmp ("verboten", + ms->check_name)) + { + continue; + } + if (0 == strcasecmp ("SKIP", ms->check_name)) + { + ret = ms; + goto done; + } + } +done: + GNUNET_free (nm); + return ret; +} + + +json_t * +TALER_KYCLOGIC_get_measures ( + const struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs, + const char *measures_spec) +{ + json_t *jmeasures; + char *nm; + bool verboten = false; + bool is_and = false; + + if ('+' == measures_spec[0]) + { + nm = GNUNET_strdup (&measures_spec[1]); + is_and = true; + } + else + { + nm = GNUNET_strdup (measures_spec); + } jmeasures = json_array (); GNUNET_assert (NULL != jmeasures); - GNUNET_assert (0 == - json_array_append_new (jmeasures, - mi)); + for (const char *tok = strtok (nm, " "); + NULL != tok; + tok = strtok (NULL, " ")) + { + const struct TALER_KYCLOGIC_Measure *ms; + json_t *mi; + + if (0 == strcasecmp ("verboten", + tok)) + { + verboten = true; + continue; + } + ms = find_measure (lrs, + tok); + if (NULL == ms) + { + GNUNET_break (0); + GNUNET_free (nm); + json_decref (jmeasures); + return NULL; + } + if (0 == strcasecmp ("verboten", + ms->check_name)) + { + verboten = true; + continue; + } + mi = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("check_name", + ms->check_name), + GNUNET_JSON_pack_string ("prog_name", + ms->prog_name), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_object_incref ("context", + ms->context))); + GNUNET_assert (0 == + json_array_append_new (jmeasures, + mi)); + } + GNUNET_free (nm); return GNUNET_JSON_PACK ( GNUNET_JSON_pack_array_steal ("measures", jmeasures), GNUNET_JSON_pack_bool ("is_and_combinator", - false), + is_and), GNUNET_JSON_pack_bool ("verboten", - false)); + verboten)); } @@ -1043,7 +1308,9 @@ TALER_KYCLOGIC_check_to_measures ( mi = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("check_name", - check->check_name), + NULL == check + ? "SKIP" + : check->check_name), GNUNET_JSON_pack_string ("prog_name", kcc->prog_name), GNUNET_JSON_pack_allow_null ( @@ -1073,6 +1340,88 @@ TALER_KYCLOGIC_rule2priority ( /** + * Perform very primitive word splitting of a command. + * + * @args command command to split + * @args extra_args extra arguments to append after the word + * @returns NULL-terminated array of words + */ +static char ** +split_words (const char *command, const char **extra_args) +{ + unsigned int i = 0; + unsigned int j = 0; + unsigned int n = 0; + char **res = NULL; + + /* Result is always NULL-terminated */ + GNUNET_array_append (res, n, NULL); + + /* Split command into words */ + while (1) + { + char *c; + + /* Skip initial whitespace before word */ + while (' ' == command[i]) + i++; + + /* Start of new word */ + j = i; + + /* Scan to end of word */ + while ( (0 != command[j]) && (' ' != command[j]) ) + j++; + + /* No new word found */ + if (i == j) + break; + + /* Append word to result */ + c = GNUNET_malloc (j - i + 1); + memcpy (c, &command[i], j - i); + c[j - i] = 0; + res[n - 1] = c; + GNUNET_array_append (res, n, NULL); + + /* Continue at end of word */ + i = j; + } + + /* Append extra args */ + if (NULL != extra_args) + { + for (const char **m = extra_args; *m; m++) + { + res[n - 1] = GNUNET_strdup (*m); + GNUNET_array_append (res, n, NULL); + } + } + + return res; +} + + +/** + * Free arguments allocated with split_words. + * + * @param args NULL-terminated array of strings to free. + */ +static void +destroy_words (char **args) +{ + if (NULL == args) + return; + for (char **m = args; *m; m++) + { + GNUNET_free (*m); + *m = NULL; + } + GNUNET_free (args); +} + + +/** * Run @a command with @a argument and return the * respective output from stdout. * @@ -1090,6 +1439,12 @@ command_output (const char *command, ssize_t ret; int sout[2]; pid_t chld; + const char *extra_args[] = { + argument, + "-c", + cfg_filename, + NULL, + }; if (0 != pipe (sout)) { @@ -1106,6 +1461,11 @@ command_output (const char *command, } if (0 == chld) { + char **argv; + + argv = split_words (command, + extra_args); + GNUNET_break (0 == close (sout[0])); GNUNET_break (0 == @@ -1115,12 +1475,9 @@ command_output (const char *command, STDOUT_FILENO)); GNUNET_break (0 == close (sout[1])); - execlp (command, - command, - argument, - "-c", - cfg_filename, - NULL); + execvp (argv[0], + argv); + destroy_words (argv); GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "exec", command); @@ -1215,6 +1572,8 @@ TALER_KYCLOGIC_kyc_trigger_from_string ( const char *trigger_s, enum TALER_KYCLOGIC_KycTriggerEvent *trigger) { + /* NOTE: if you change this, also change + the code in src/json/json_helper.c! */ struct { const char *in; @@ -1226,6 +1585,8 @@ TALER_KYCLOGIC_kyc_trigger_from_string ( { "BALANCE", TALER_KYCLOGIC_KYC_TRIGGER_WALLET_BALANCE }, { "CLOSE", TALER_KYCLOGIC_KYC_TRIGGER_RESERVE_CLOSE }, { "AGGREGATE", TALER_KYCLOGIC_KYC_TRIGGER_AGGREGATE }, + { "TRANSACTION", TALER_KYCLOGIC_KYC_TRIGGER_TRANSACTION }, + { "REFUND", TALER_KYCLOGIC_KYC_TRIGGER_REFUND }, { NULL, 0 } }; @@ -1243,33 +1604,6 @@ TALER_KYCLOGIC_kyc_trigger_from_string ( } -const char * -TALER_KYCLOGIC_kyc_trigger2s ( - enum TALER_KYCLOGIC_KycTriggerEvent trigger) -{ - switch (trigger) - { - case TALER_KYCLOGIC_KYC_TRIGGER_NONE: - GNUNET_break (0); - return NULL; - case TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW: - return "WITHDRAW"; - case TALER_KYCLOGIC_KYC_TRIGGER_DEPOSIT: - return "DEPOSIT"; - case TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE: - return "MERGE"; - case TALER_KYCLOGIC_KYC_TRIGGER_WALLET_BALANCE: - return "BALANCE"; - case TALER_KYCLOGIC_KYC_TRIGGER_RESERVE_CLOSE: - return "CLOSE"; - case TALER_KYCLOGIC_KYC_TRIGGER_AGGREGATE: - return "AGGREGATE"; - } - GNUNET_break (0); - return NULL; -} - - json_t * TALER_KYCLOGIC_get_wallet_thresholds (void) { @@ -1314,8 +1648,8 @@ load_logic (const struct GNUNET_CONFIGURATION_Handle *cfg, "libtaler_plugin_kyclogic_%s", name); for (unsigned int i = 0; i<num_kyc_logics; i++) - if (0 == strcmp (lib_name, - kyc_logics[i]->library_name)) + if (0 == strcasecmp (lib_name, + kyc_logics[i]->library_name)) { GNUNET_free (lib_name); return kyc_logics[i]; @@ -1348,7 +1682,6 @@ add_provider (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section) { char *logic; - char *converter; struct TALER_KYCLOGIC_Plugin *lp; struct TALER_KYCLOGIC_ProviderDetails *pd; @@ -1358,24 +1691,12 @@ add_provider (const struct GNUNET_CONFIGURATION_Handle *cfg, if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, section, - "CONVERTER", - &converter)) - { - GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - section, - "CONVERTER"); - return GNUNET_SYSERR; - } - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, - section, "LOGIC", &logic)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, section, "LOGIC"); - GNUNET_free (converter); return GNUNET_SYSERR; } lp = load_logic (cfg, @@ -1387,17 +1708,13 @@ add_provider (const struct GNUNET_CONFIGURATION_Handle *cfg, "LOGIC", "logic plugin could not be loaded"); GNUNET_free (logic); - GNUNET_free (converter); return GNUNET_SYSERR; } GNUNET_free (logic); pd = lp->load_configuration (lp->cls, section); if (NULL == pd) - { - GNUNET_free (converter); return GNUNET_SYSERR; - } { struct TALER_KYCLOGIC_KycProvider *kp; @@ -1405,7 +1722,6 @@ add_provider (const struct GNUNET_CONFIGURATION_Handle *cfg, kp = GNUNET_new (struct TALER_KYCLOGIC_KycProvider); kp->provider_name = GNUNET_strdup (§ion[strlen ("kyc-provider-")]); - kp->converter_name = converter; kp->logic = lp; kp->pd = pd; GNUNET_array_append (kyc_providers, @@ -1509,9 +1825,7 @@ static enum GNUNET_GenericReturnValue add_check (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section) { - bool voluntary; enum TALER_KYCLOGIC_CheckType ct; - char *form_name = NULL; char *description = NULL; json_t *description_i18n = NULL; char *requires = NULL; @@ -1528,11 +1842,6 @@ add_check (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Parsing KYC check %s\n", section); - voluntary = (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_yesno (cfg, - section, - "VOLUNTARY")); - { char *type_s; @@ -1706,7 +2015,6 @@ add_check (const struct GNUNET_CONFIGURATION_Handle *cfg, break; } kc->check_name = GNUNET_strdup (§ion[strlen ("kyc-check-")]); - kc->voluntary = voluntary; kc->description = description; kc->description_i18n = description_i18n; kc->fallback = fallback; @@ -1728,7 +2036,6 @@ add_check (const struct GNUNET_CONFIGURATION_Handle *cfg, return GNUNET_OK; fail: - GNUNET_free (form_name); GNUNET_free (description); json_decref (description_i18n); GNUNET_free (requires); @@ -1802,11 +2109,10 @@ add_rule (const struct GNUNET_CONFIGURATION_Handle *cfg, "amount required"); return GNUNET_SYSERR; } - if (GNUNET_YES != - GNUNET_CONFIGURATION_get_value_yesno (cfg, - section, - "EXPOSED")) - exposed = false; + exposed = (GNUNET_YES == + GNUNET_CONFIGURATION_get_value_yesno (cfg, + section, + "EXPOSED")); { enum GNUNET_GenericReturnValue r; @@ -1884,19 +2190,23 @@ add_rule (const struct GNUNET_CONFIGURATION_Handle *cfg, } GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Adding KYC rule %s\n", - section); - { - struct TALER_KYCLOGIC_KycRule kt; + "Adding KYC rule %s for trigger %d with threshold %s\n", + section, + (int) ot, + TALER_amount2s (&threshold)); + { + struct TALER_KYCLOGIC_KycRule kt = { + .lrs = &default_rules, + .rule_name = GNUNET_strdup (§ion[strlen ("kyc-rule-")]), + .timeframe = timeframe, + .threshold = threshold, + .trigger = ot, + .is_and_combinator = is_and, + .exposed = exposed, + .display_priority = 0, + .verboten = false + }; - kt.lrs = &default_rules; - kt.rule_name = GNUNET_strdup (§ion[strlen ("kyc-rule-")]); - kt.timeframe = timeframe; - kt.threshold = threshold; - kt.trigger = ot; - kt.is_and_combinator = is_and; - kt.exposed = exposed; - kt.verboten = false; add_tokens (measures, " ", &kt.next_measures, @@ -2089,6 +2399,7 @@ static enum GNUNET_GenericReturnValue add_measure (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section) { + bool voluntary; char *check_name = NULL; char *context_str = NULL; char *program = NULL; @@ -2117,6 +2428,11 @@ add_measure (const struct GNUNET_CONFIGURATION_Handle *cfg, "PROGRAM"); goto fail; } + voluntary = (GNUNET_YES == + GNUNET_CONFIGURATION_get_value_yesno (cfg, + section, + "VOLUNTARY")); + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, section, @@ -2148,6 +2464,7 @@ add_measure (const struct GNUNET_CONFIGURATION_Handle *cfg, m.check_name = check_name; m.prog_name = program; m.context = context; + m.voluntary = voluntary; GNUNET_array_append (default_rules.custom_measures, default_rules.num_custom_measures, m); @@ -2263,6 +2580,9 @@ TALER_KYCLOGIC_kyc_init ( const char *measure_name = rule->next_measures[j]; const struct TALER_KYCLOGIC_Measure *m; + if (0 == strcmp ("verboten", + measure_name)) + continue; m = find_measure (&default_rules, measure_name); if (NULL == m) @@ -2357,7 +2677,6 @@ TALER_KYCLOGIC_kyc_done (void) kp->logic->unload_configuration (kp->pd); GNUNET_free (kp->provider_name); - GNUNET_free (kp->converter_name); GNUNET_free (kp); } GNUNET_array_grow (kyc_providers, @@ -2475,8 +2794,8 @@ TALER_KYCLOGIC_get_original_measure ( } for (unsigned int i = 0; i<num_kyc_checks; i++) - if (0 == strcmp (measure->check_name, - kyc_checks[i]->check_name)) + if (0 == strcasecmp (measure->check_name, + kyc_checks[i]->check_name)) { kcc->check = kyc_checks[i]; kcc->prog_name = measure->prog_name; @@ -2512,8 +2831,8 @@ TALER_KYCLOGIC_requirements_to_check ( { for (unsigned int i = 0; i<kyc_rule->num_measures; i++) { - if (0 != strcmp (measure_name, - kyc_rule->next_measures[i])) + if (0 != strcasecmp (measure_name, + kyc_rule->next_measures[i])) continue; found = true; break; @@ -2556,8 +2875,8 @@ TALER_KYCLOGIC_requirements_to_check ( } for (unsigned int i = 0; i<num_kyc_checks; i++) - if (0 == strcmp (measure->check_name, - kyc_checks[i]->check_name)) + if (0 == strcasecmp (measure->check_name, + kyc_checks[i]->check_name)) { kcc->check = kyc_checks[i]; kcc->prog_name = measure->prog_name; @@ -2624,8 +2943,8 @@ TALER_KYCLOGIC_kyc_get_details ( = kyc_providers[i]; if (0 != - strcmp (kp->logic->name, - logic_name)) + strcasecmp (kp->logic->name, + logic_name)) continue; if (GNUNET_OK != cb (cb_cls, @@ -2778,7 +3097,14 @@ TALER_KYCLOGIC_kyc_test_required ( = &lrs->kyc_rules[i]; if (event != rule->trigger) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Rule %u is for a different trigger (%d/%d)\n", + i, + (int) event, + (int) rule->trigger); continue; + } if (have_threshold) { GNUNET_assert (GNUNET_OK == @@ -2792,14 +3118,23 @@ TALER_KYCLOGIC_kyc_test_required ( have_threshold = true; } GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Matched rule %u with timeframe %s\n", + "Matched rule %u with timeframe %s and threshold %s\n", i, GNUNET_TIME_relative2s (rule->timeframe, - true)); + true), + TALER_amount2s (&rule->threshold)); range = GNUNET_TIME_relative_max (range, rule->timeframe); } + if (! have_threshold) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "No rules apply\n"); + *triggered_rule = NULL; + return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; + } + { struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); @@ -2828,6 +3163,7 @@ json_t * TALER_KYCLOGIC_measure_to_requirement ( const char *check_name, const char *prog_name, + const json_t *context, const struct TALER_AccountAccessTokenP *access_token, size_t offset, uint64_t legitimization_measure_row_id) @@ -2875,6 +3211,9 @@ TALER_KYCLOGIC_measure_to_requirement ( kc->details.form.name), GNUNET_JSON_pack_string ("id", xids), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_object_incref ("context", + (json_t *) context)), GNUNET_JSON_pack_string ("description", kc->description), GNUNET_JSON_pack_allow_null ( @@ -3162,6 +3501,11 @@ TALER_KYCLOGIC_check_to_provider (const char *check_name) { struct TALER_KYCLOGIC_KycCheck *kc; + if (NULL == check_name) + return NULL; + if (0 == strcasecmp (check_name, + "SKIP")) + return NULL; kc = find_check (check_name); switch (kc->type) { @@ -3262,7 +3606,7 @@ handle_aml_output ( &apr->details.success.to_investigate), NULL), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_array_const ( + GNUNET_JSON_spec_object_const ( "properties", &apr->details.success.account_properties), NULL), @@ -3496,6 +3840,13 @@ TALER_KYCLOGIC_run_aml_program2 ( { json_t *input; + const char *extra_args[] = { + "-c", + cfg_filename, + NULL, + }; + + char **args; input = GNUNET_JSON_PACK ( GNUNET_JSON_pack_allow_null ( @@ -3508,15 +3859,22 @@ TALER_KYCLOGIC_run_aml_program2 ( GNUNET_JSON_pack_array_incref ("kyc_history", (json_t *) kyc_history) ); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Running AML program %s\n", + prog->command); + args = split_words (prog->command, extra_args); + GNUNET_assert (NULL != args); + GNUNET_assert (NULL != args[0]); + json_dumpf (input, + stderr, + JSON_INDENT (2)); aprh->proc = TALER_JSON_external_conversion_start ( input, &handle_aml_output, aprh, - prog->command, - prog->command, - "-c", - cfg_filename, - NULL); + args[0], + (const char **) args); + destroy_words (args); json_decref (input); } return aprh; @@ -3561,4 +3919,73 @@ TALER_KYCLOGIC_run_aml_program_cancel ( } +json_t * +TALER_KYCLOGIC_get_hard_limits () +{ + const struct TALER_KYCLOGIC_KycRule *rules + = default_rules.kyc_rules; + unsigned int num_rules + = default_rules.num_kyc_rules; + json_t *hard_limits; + + hard_limits = json_array (); + GNUNET_assert (NULL != hard_limits); + for (unsigned int i = 0; i<num_rules; i++) + { + const struct TALER_KYCLOGIC_KycRule *rule = &rules[i]; + json_t *hard_limit; + + if (! rule->verboten) + continue; + if (! rule->exposed) + continue; + hard_limit = GNUNET_JSON_PACK ( + TALER_JSON_pack_kycte ("operation_type", + rule->trigger), + GNUNET_JSON_pack_time_rel ("timeframe", + rule->timeframe), + TALER_JSON_pack_amount ("threshold", + &rule->threshold) + ); + GNUNET_assert (0 == + json_array_append_new (hard_limits, + hard_limit)); + } + return hard_limits; +} + + +json_t * +TALER_KYCLOGIC_get_zero_limits () +{ + const struct TALER_KYCLOGIC_KycRule *rules + = default_rules.kyc_rules; + unsigned int num_rules + = default_rules.num_kyc_rules; + json_t *zero_limits; + + zero_limits = json_array (); + GNUNET_assert (NULL != zero_limits); + for (unsigned int i = 0; i<num_rules; i++) + { + const struct TALER_KYCLOGIC_KycRule *rule = &rules[i]; + json_t *zero_limit; + + if (! rule->exposed) + continue; + if (rule->verboten) + continue; /* see: hard_limits */ + if (! TALER_amount_is_zero (&rule->threshold)) + continue; + zero_limit = GNUNET_JSON_PACK ( + TALER_JSON_pack_kycte ("operation_type", + rule->trigger)); + GNUNET_assert (0 == + json_array_append_new (zero_limits, + zero_limit)); + } + return zero_limits; +} + + /* end of kyclogic_api.c */ diff --git a/src/kyclogic/plugin_kyclogic_kycaid.c b/src/kyclogic/plugin_kyclogic_kycaid.c index 243ff7c34..fcf94984b 100644 --- a/src/kyclogic/plugin_kyclogic_kycaid.c +++ b/src/kyclogic/plugin_kyclogic_kycaid.c @@ -893,9 +893,8 @@ webhook_conversion_cb (void *cls, return; } expiration = GNUNET_TIME_relative_to_absolute (wh->pd->validity); - resp = MHD_create_response_from_buffer (0, - "", - MHD_RESPMEM_PERSISTENT); + resp = MHD_create_response_from_buffer_static (0, + ""); wh->cb (wh->cb_cls, wh->process_row, &wh->h_payto, @@ -953,9 +952,8 @@ handle_webhook_finished (void *cls, profile_status)) ? TALER_KYCLOGIC_STATUS_PENDING : TALER_KYCLOGIC_STATUS_USER_ABORTED; - resp = MHD_create_response_from_buffer (0, - "", - MHD_RESPMEM_PERSISTENT); + resp = MHD_create_response_from_buffer_static (0, + ""); wh->cb (wh->cb_cls, wh->process_row, &wh->h_payto, @@ -969,16 +967,22 @@ handle_webhook_finished (void *cls, resp); break; } - wh->econ - = TALER_JSON_external_conversion_start ( - j, - &webhook_conversion_cb, - wh, - wh->pd->conversion_helper, - wh->pd->conversion_helper, - "-a", - wh->pd->auth_token, - NULL); + { + const char *argv[] = { + wh->pd->conversion_helper, + "-a", + wh->pd->auth_token, + NULL, + }; + + wh->econ + = TALER_JSON_external_conversion_start ( + j, + &webhook_conversion_cb, + wh, + wh->pd->conversion_helper, + argv); + } if (NULL == wh->econ) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -1344,9 +1348,8 @@ kycaid_webhook (void *cls, "Webhook called with non-completion status: %s\n", type); wh->response_code = MHD_HTTP_NO_CONTENT; - wh->resp = MHD_create_response_from_buffer (0, - "", - MHD_RESPMEM_PERSISTENT); + wh->resp = MHD_create_response_from_buffer_static (0, + ""); wh->task = GNUNET_SCHEDULER_add_now (&async_webhook_reply, wh); return wh; @@ -1396,6 +1399,10 @@ kycaid_webhook (void *cls, * @return NULL on error, otherwise a `struct TALER_KYCLOGIC_Plugin` */ void * +libtaler_plugin_kyclogic_kycaid_init (void *cls); + +/* declaration to avoid compiler warning */ +void * libtaler_plugin_kyclogic_kycaid_init (void *cls) { const struct GNUNET_CONFIGURATION_Handle *cfg = cls; @@ -1458,6 +1465,10 @@ libtaler_plugin_kyclogic_kycaid_init (void *cls) * @return NULL (always) */ void * +libtaler_plugin_kyclogic_kycaid_done (void *cls); + +/* declaration to avoid compiler warning */ +void * libtaler_plugin_kyclogic_kycaid_done (void *cls) { struct TALER_KYCLOGIC_Plugin *plugin = cls; diff --git a/src/kyclogic/plugin_kyclogic_oauth2.c b/src/kyclogic/plugin_kyclogic_oauth2.c index da3f0f219..a94e8790b 100644 --- a/src/kyclogic/plugin_kyclogic_oauth2.c +++ b/src/kyclogic/plugin_kyclogic_oauth2.c @@ -426,8 +426,8 @@ oauth2_load_configuration (void *cls, const char *extra = strchr (s, '#'); const char *slash = strrchr (s, '/'); - if ( (0 != strcmp (extra, - "#setup")) || + if ( (0 != strcasecmp (extra, + "#setup")) || (NULL == slash) ) { GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, @@ -1057,9 +1057,8 @@ converted_proof_cb (void *cls, ph->provider_user_id = GNUNET_strdup (id); } ph->status = TALER_KYCLOGIC_STATUS_SUCCESS; - ph->response = MHD_create_response_from_buffer (0, - "", - MHD_RESPMEM_PERSISTENT); + ph->response = MHD_create_response_from_buffer_static (0, + ""); GNUNET_assert (NULL != ph->response); GNUNET_break (MHD_YES == MHD_add_response_header ( @@ -1085,6 +1084,10 @@ parse_proof_success_reply (struct TALER_KYCLOGIC_ProofHandle *ph, const json_t *j) { const struct TALER_KYCLOGIC_ProviderDetails *pd = ph->pd; + const char *argv[] = { + pd->conversion_binary, + NULL, + }; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Calling converter `%s' with JSON\n", @@ -1097,12 +1100,11 @@ parse_proof_success_reply (struct TALER_KYCLOGIC_ProofHandle *ph, &converted_proof_cb, ph, pd->conversion_binary, - pd->conversion_binary, - NULL); + argv); if (NULL != ph->ec) return; GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to start KYCAID conversion helper `%s'\n", + "Failed to start OAUTH2 conversion helper `%s'\n", pd->conversion_binary); ph->status = TALER_KYCLOGIC_STATUS_INTERNAL_ERROR; ph->http_status = MHD_HTTP_INTERNAL_SERVER_ERROR; @@ -1477,14 +1479,14 @@ oauth2_proof (void *cls, "OAuth2 process %llu failed with error `%s'\n", (unsigned long long) process_row, err); - if (0 == strcmp (err, - "server_error")) + if (0 == strcasecmp (err, + "server_error")) ph->status = TALER_KYCLOGIC_STATUS_PROVIDER_FAILED; - else if (0 == strcmp (err, - "unauthorized_client")) + else if (0 == strcasecmp (err, + "unauthorized_client")) ph->status = TALER_KYCLOGIC_STATUS_FAILED; - else if (0 == strcmp (err, - "temporarily_unavailable")) + else if (0 == strcasecmp (err, + "temporarily_unavailable")) ph->status = TALER_KYCLOGIC_STATUS_PENDING; else ph->status = TALER_KYCLOGIC_STATUS_INTERNAL_ERROR; @@ -1612,9 +1614,8 @@ wh_return_not_found (void *cls) struct MHD_Response *response; wh->task = NULL; - response = MHD_create_response_from_buffer (0, - "", - MHD_RESPMEM_PERSISTENT); + response = MHD_create_response_from_buffer_static (0, + ""); wh->cb (wh->cb_cls, 0LLU, NULL, @@ -1698,6 +1699,10 @@ oauth2_webhook_cancel (struct TALER_KYCLOGIC_WebhookHandle *wh) * @return NULL on error, otherwise a `struct TALER_KYCLOGIC_Plugin` */ void * +libtaler_plugin_kyclogic_oauth2_init (void *cls); + +/* declaration to avoid compiler warning */ +void * libtaler_plugin_kyclogic_oauth2_init (void *cls) { const struct GNUNET_CONFIGURATION_Handle *cfg = cls; @@ -1759,6 +1764,10 @@ libtaler_plugin_kyclogic_oauth2_init (void *cls) * @return NULL (always) */ void * +libtaler_plugin_kyclogic_oauth2_done (void *cls); + +/* declaration to avoid compiler warning */ +void * libtaler_plugin_kyclogic_oauth2_done (void *cls) { struct TALER_KYCLOGIC_Plugin *plugin = cls; diff --git a/src/kyclogic/plugin_kyclogic_persona.c b/src/kyclogic/plugin_kyclogic_persona.c index 975003146..6b957756e 100644 --- a/src/kyclogic/plugin_kyclogic_persona.c +++ b/src/kyclogic/plugin_kyclogic_persona.c @@ -1022,6 +1022,13 @@ start_conversion (const struct TALER_KYCLOGIC_ProviderDetails *pd, TALER_JSON_JsonCallback cb, void *cb_cls) { + const char *argv[] = { + pd->conversion_binary, + "-a", + pd->auth_token, + NULL, + }; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Calling converter `%s' with JSON\n", pd->conversion_binary); @@ -1033,11 +1040,7 @@ start_conversion (const struct TALER_KYCLOGIC_ProviderDetails *pd, cb, cb_cls, pd->conversion_binary, - pd->conversion_binary, - "-a", - pd->auth_token, - NULL - ); + argv); } @@ -1073,9 +1076,8 @@ proof_post_conversion_cb (void *cls, return; } expiration = GNUNET_TIME_relative_to_absolute (ph->pd->validity); - resp = MHD_create_response_from_buffer (0, - "", - MHD_RESPMEM_PERSISTENT); + resp = MHD_create_response_from_buffer_static (0, + ""); GNUNET_break (MHD_YES == MHD_add_response_header (resp, MHD_HTTP_HEADER_LOCATION, @@ -1138,8 +1140,8 @@ handle_proof_finished (void *cls, GNUNET_JSON_parse (data, spec, NULL, NULL)) || - (0 != strcmp (type, - "inquiry")) ) + (0 != strcasecmp (type, + "inquiry")) ) { GNUNET_break_op (0); return_invalid_response (ph, @@ -1220,8 +1222,8 @@ handle_proof_finished (void *cls, "data"), "id")); - if (0 != strcmp (status, - "completed")) + if (0 != strcasecmp (status, + "completed")) { proof_generic_reply ( ph, @@ -1565,9 +1567,8 @@ webhook_generic_reply (struct TALER_KYCLOGIC_WebhookHandle *wh, expiration = GNUNET_TIME_relative_to_absolute (wh->pd->validity); else expiration = GNUNET_TIME_UNIT_ZERO_ABS; - resp = MHD_create_response_from_buffer (0, - "", - MHD_RESPMEM_PERSISTENT); + resp = MHD_create_response_from_buffer_static (0, + ""); TALER_MHD_add_global_headers (resp); wh->cb (wh->cb_cls, wh->process_row, @@ -1675,8 +1676,8 @@ handle_webhook_finished (void *cls, GNUNET_JSON_parse (data, spec, NULL, NULL)) || - (0 != strcmp (type, - "inquiry")) ) + (0 != strcasecmp (type, + "inquiry")) ) { GNUNET_break_op (0); json_dumpf (j, @@ -1755,8 +1756,8 @@ handle_webhook_finished (void *cls, "data"), "id")); - if (0 != strcmp (status, - "completed")) + if (0 != strcasecmp (status, + "completed")) { webhook_generic_reply (wh, TALER_KYCLOGIC_STATUS_FAILED, @@ -2171,6 +2172,10 @@ persona_webhook (void *cls, * @return NULL on error, otherwise a `struct TALER_KYCLOGIC_Plugin` */ void * +libtaler_plugin_kyclogic_persona_init (void *cls); + +/* declaration to avoid compiler warning */ +void * libtaler_plugin_kyclogic_persona_init (void *cls) { const struct GNUNET_CONFIGURATION_Handle *cfg = cls; @@ -2242,6 +2247,11 @@ libtaler_plugin_kyclogic_persona_init (void *cls) * @return NULL (always) */ void * +libtaler_plugin_kyclogic_persona_done (void *cls); + +/* declaration to avoid compiler warning */ + +void * libtaler_plugin_kyclogic_persona_done (void *cls) { struct TALER_KYCLOGIC_Plugin *plugin = cls; diff --git a/src/kyclogic/plugin_kyclogic_template.c b/src/kyclogic/plugin_kyclogic_template.c index 54f36e6f2..b7fce18a7 100644 --- a/src/kyclogic/plugin_kyclogic_template.c +++ b/src/kyclogic/plugin_kyclogic_template.c @@ -384,6 +384,10 @@ template_webhook (void *cls, * @return NULL on error, otherwise a `struct TALER_KYCLOGIC_Plugin` */ void * +libtaler_plugin_kyclogic_template_init (void *cls); + +/* declaration to avoid compiler warning */ +void * libtaler_plugin_kyclogic_template_init (void *cls) { const struct GNUNET_CONFIGURATION_Handle *cfg = cls; @@ -446,6 +450,10 @@ libtaler_plugin_kyclogic_template_init (void *cls) * @return NULL (always) */ void * +libtaler_plugin_kyclogic_template_done (void *cls); + +/* declaration to avoid compiler warning */ +void * libtaler_plugin_kyclogic_template_done (void *cls) { struct TALER_KYCLOGIC_Plugin *plugin = cls; diff --git a/src/kyclogic/taler-exchange-helper-measure-freeze b/src/kyclogic/taler-exchange-helper-measure-freeze index 3505f5945..9be652372 100755 --- a/src/kyclogic/taler-exchange-helper-measure-freeze +++ b/src/kyclogic/taler-exchange-helper-measure-freeze @@ -85,11 +85,13 @@ EXPIRATION=$((3600 * 30 + $(date +%s))) # See https://docs.taler.net/taler-exchange-manual.html#tsref-type-AmlOutcome # for the required output format. +# NOTE: new_check is not yet supported! #9124 jq -n \ --arg expiration "$EXPIRATION" \ '{ "to_investigate": true, "new_rules" : { "new_check" : "info-frozen", + "custom_measures" : {}, "expiration_time" : { "t_s": $expiration }, "rules" : [ { diff --git a/src/kyclogic/taler-exchange-helper-measure-test-form b/src/kyclogic/taler-exchange-helper-measure-test-form index ccddf346a..f5bd3767a 100755 --- a/src/kyclogic/taler-exchange-helper-measure-test-form +++ b/src/kyclogic/taler-exchange-helper-measure-test-form @@ -102,12 +102,14 @@ CURRENCY=$(taler-config -c $CONF -s taler -o currency) # See https://docs.taler.net/taler-exchange-manual.html#tsref-type-AmlOutcome # for the required output format. +# NOTE: new_check is not yet supported! #9124 jq -n \ --argjson expiration "$EXPIRATION" \ --arg currency "$CURRENCY" \ '{ "to_investigate": false, "new_rules" : { "new_check" : "info-oauth-test-passed", + "custom_measures" : {}, "expiration_time" : { "t_s": $expiration }, "rules" : [ { diff --git a/src/kyclogic/taler-exchange-helper-measure-test-oauth b/src/kyclogic/taler-exchange-helper-measure-test-oauth index 4d6c4a43a..fcdaa255d 100755 --- a/src/kyclogic/taler-exchange-helper-measure-test-oauth +++ b/src/kyclogic/taler-exchange-helper-measure-test-oauth @@ -98,11 +98,14 @@ EXPIRATION=$((3600 * 30 + $(date +%s))) # See https://docs.taler.net/taler-exchange-manual.html#tsref-type-AmlOutcome # for the required output format. +# NOTE: new_check is not yet supported! #9124 + jq -n \ --argjson expiration "$EXPIRATION" \ '{ "to_investigate": false, "new_rules" : { "new_check" : "info-oauth-test-passed", + "custom_measures" : {}, "expiration_time" : { "t_s": $expiration }, "rules" : [ { diff --git a/src/kyclogic/taler-exchange-kyc-tester.c b/src/kyclogic/taler-exchange-kyc-tester.c index b4d752525..14af603ab 100644 --- a/src/kyclogic/taler-exchange-kyc-tester.c +++ b/src/kyclogic/taler-exchange-kyc-tester.c @@ -1325,7 +1325,7 @@ exchange_serve_process_config (void) static void do_shutdown (void *cls) { - struct MHD_Daemon *mhd; + struct MHD_Daemon *my_mhd; struct ProofRequestState *rs; (void) cls; @@ -1345,9 +1345,9 @@ do_shutdown (void *cls) } kyc_webhook_cleanup (); TALER_KYCLOGIC_kyc_done (); - mhd = TALER_MHD_daemon_stop (); - if (NULL != mhd) - MHD_stop_daemon (mhd); + my_mhd = TALER_MHD_daemon_stop (); + if (NULL != my_mhd) + MHD_stop_daemon (my_mhd); if (NULL != TEKT_curl_ctx) { GNUNET_CURL_fini (TEKT_curl_ctx); diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 8924ee604..88d00765f 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -18,7 +18,7 @@ lib_LTLIBRARIES = \ libtalerexchange.la libtalerexchange_la_LDFLAGS = \ - -version-info 9:0:0 \ + -version-info 12:0:0 \ -no-undefined libtalerexchange_la_SOURCES = \ exchange_api_add_aml_decision.c \ @@ -78,6 +78,7 @@ libtalerexchange_la_SOURCES = \ exchange_api_reserves_get_attestable.c \ exchange_api_reserves_history.c \ exchange_api_reserves_open.c \ + exchange_api_restrictions.c \ exchange_api_stefan.c \ exchange_api_transfers_get.c libtalerexchange_la_LIBADD = \ diff --git a/src/lib/exchange_api_add_aml_decision.c b/src/lib/exchange_api_add_aml_decision.c index 53cd04eb5..e60b88c6c 100644 --- a/src/lib/exchange_api_add_aml_decision.c +++ b/src/lib/exchange_api_add_aml_decision.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2023 Taler Systems SA + 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 @@ -119,18 +119,19 @@ handle_add_aml_decision_finished (void *cls, &adr); wh->cb = NULL; } - TALER_EXCHANGE_add_aml_decision_cancel (wh); + TALER_EXCHANGE_post_aml_decision_cancel (wh); } struct TALER_EXCHANGE_AddAmlDecision * -TALER_EXCHANGE_add_aml_decision ( +TALER_EXCHANGE_post_aml_decision ( struct GNUNET_CURL_Context *ctx, const char *url, const struct TALER_PaytoHashP *h_payto, + const char *payto_uri, struct GNUNET_TIME_Timestamp decision_time, const char *successor_measure, - const char *new_measure, + const char *new_measures, struct GNUNET_TIME_Timestamp expiration_time, unsigned int num_rules, const struct TALER_EXCHANGE_AccountRule *rules, @@ -167,9 +168,8 @@ TALER_EXCHANGE_add_aml_decision ( json_array_append_new (ameasures, json_string (al->measures[j]))); rule = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("operation_type", - TALER_KYCLOGIC_kyc_trigger2s (al->operation_type) - ), + TALER_JSON_pack_kycte ("operation_type", + al->operation_type), TALER_JSON_pack_amount ("threshold", &al->threshold), GNUNET_JSON_pack_time_rel ("timeframe", @@ -230,7 +230,7 @@ TALER_EXCHANGE_add_aml_decision ( h_payto, new_rules, properties, - new_measure, + new_measures, keep_investigating, officer_priv, &officer_sig); @@ -270,13 +270,16 @@ TALER_EXCHANGE_add_aml_decision ( justification), GNUNET_JSON_pack_data_auto ("h_payto", h_payto), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("payto_uri", + payto_uri)), GNUNET_JSON_pack_object_steal ("new_rules", new_rules), GNUNET_JSON_pack_object_incref ("properties", (json_t *) properties), GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_string ("new_measure", - new_measure)), + GNUNET_JSON_pack_string ("new_measures", + new_measures)), GNUNET_JSON_pack_bool ("keep_investigating", keep_investigating), GNUNET_JSON_pack_data_auto ("officer_sig", @@ -308,7 +311,7 @@ TALER_EXCHANGE_add_aml_decision ( wh); if (NULL == wh->job) { - TALER_EXCHANGE_add_aml_decision_cancel (wh); + TALER_EXCHANGE_post_aml_decision_cancel (wh); return NULL; } return wh; @@ -316,7 +319,7 @@ TALER_EXCHANGE_add_aml_decision ( void -TALER_EXCHANGE_add_aml_decision_cancel ( +TALER_EXCHANGE_post_aml_decision_cancel ( struct TALER_EXCHANGE_AddAmlDecision *wh) { if (NULL != wh->job) diff --git a/src/lib/exchange_api_age_withdraw_reveal.c b/src/lib/exchange_api_age_withdraw_reveal.c index a48e51638..3cb20739b 100644 --- a/src/lib/exchange_api_age_withdraw_reveal.c +++ b/src/lib/exchange_api_age_withdraw_reveal.c @@ -141,7 +141,7 @@ age_withdraw_reveal_ok ( /* Reconstruct the coins and unblind the signatures */ json_array_foreach (j_sigs, n, j_sig) { - struct GNUNET_JSON_Specification spec[] = { + struct GNUNET_JSON_Specification ispec[] = { TALER_JSON_spec_blinded_denom_sig (NULL, &denom_sigs[n]), GNUNET_JSON_spec_end () @@ -149,13 +149,12 @@ age_withdraw_reveal_ok ( if (GNUNET_OK != GNUNET_JSON_parse (j_sig, - spec, + ispec, NULL, NULL)) { GNUNET_break_op (0); return GNUNET_SYSERR; } - } response.details.ok.num_sigs = awrh->num_coins; diff --git a/src/lib/exchange_api_batch_deposit.c b/src/lib/exchange_api_batch_deposit.c index 3dab64526..1c169495c 100644 --- a/src/lib/exchange_api_batch_deposit.c +++ b/src/lib/exchange_api_batch_deposit.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2023 Taler Systems SA + Copyright (C) 2014-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 @@ -436,9 +436,104 @@ handle_deposit_finished (void *cls, break; case MHD_HTTP_CONFLICT: { + dr->hr.ec = TALER_JSON_get_error_code (j); + dr->hr.hint = TALER_JSON_get_error_hint (j); + switch (dr->hr.ec) + { + case TALER_EC_EXCHANGE_GENERIC_INSUFFICIENT_FUNDS: + { + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_fixed_auto ( + "coin_pub", + &dr->details.conflict.details + .insufficient_funds.coin_pub), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (j, + spec, + NULL, NULL)) + { + GNUNET_break_op (0); + dr->hr.http_status = 0; + dr->hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + break; + } + } + break; + case TALER_EC_EXCHANGE_GENERIC_COIN_CONFLICTING_AGE_HASH: + { + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_fixed_auto ( + "coin_pub", + &dr->details.conflict.details + .coin_conflicting_age_hash.coin_pub), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (j, + spec, + NULL, NULL)) + { + GNUNET_break_op (0); + dr->hr.http_status = 0; + dr->hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + break; + } + } + break; + case TALER_EC_EXCHANGE_GENERIC_COIN_CONFLICTING_DENOMINATION_KEY: + { + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_fixed_auto ( + "coin_pub", + &dr->details.conflict.details + .coin_conflicting_denomination_key.coin_pub), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (j, + spec, + NULL, NULL)) + { + GNUNET_break_op (0); + dr->hr.http_status = 0; + dr->hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + break; + } + } + break; + case TALER_EC_EXCHANGE_DEPOSIT_CONFLICTING_CONTRACT: + break; + default: + GNUNET_break_op (0); + break; + } + } + break; + case MHD_HTTP_GONE: + /* could happen if denomination was revoked */ + /* Note: one might want to check /keys for revocation + signature here, alas tricky in case our /keys + is outdated => left to clients */ + dr->hr.ec = TALER_JSON_get_error_code (j); + dr->hr.hint = TALER_JSON_get_error_hint (j); + break; + case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS: + { struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_fixed_auto ("coin_pub", - &dr->details.conflict.coin_pub), + GNUNET_JSON_spec_fixed_auto ( + "h_payto", + &dr->details.unavailable_for_legal_reasons.h_payto), + GNUNET_JSON_spec_uint64 ( + "requirement_row", + &dr->details.unavailable_for_legal_reasons.requirement_row), + GNUNET_JSON_spec_bool ( + "bad_kyc_auth", + &dr->details.unavailable_for_legal_reasons.bad_kyc_auth), GNUNET_JSON_spec_end () }; @@ -452,18 +547,8 @@ handle_deposit_finished (void *cls, dr->hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; break; } - dr->hr.ec = TALER_JSON_get_error_code (j); - dr->hr.hint = TALER_JSON_get_error_hint (j); } break; - case MHD_HTTP_GONE: - /* could happen if denomination was revoked */ - /* Note: one might want to check /keys for revocation - signature here, alas tricky in case our /keys - is outdated => left to clients */ - dr->hr.ec = TALER_JSON_get_error_code (j); - dr->hr.hint = TALER_JSON_get_error_hint (j); - break; case MHD_HTTP_INTERNAL_SERVER_ERROR: dr->hr.ec = TALER_JSON_get_error_code (j); dr->hr.hint = TALER_JSON_get_error_hint (j); diff --git a/src/lib/exchange_api_get_kyc_statistics.c b/src/lib/exchange_api_get_kyc_statistics.c index d029e44b5..4183e9118 100644 --- a/src/lib/exchange_api_get_kyc_statistics.c +++ b/src/lib/exchange_api_get_kyc_statistics.c @@ -182,7 +182,7 @@ handle_lookup_finished (void *cls, struct TALER_EXCHANGE_KycGetStatisticsHandle * -TALER_EXCHANGE_get_kyc_statistics ( +TALER_EXCHANGE_kyc_get_statistics ( struct GNUNET_CURL_Context *ctx, const char *exchange_url, const char *name, diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c index f614ff3c2..a282fdb63 100644 --- a/src/lib/exchange_api_handle.c +++ b/src/lib/exchange_api_handle.c @@ -40,12 +40,12 @@ * Which version of the Taler protocol is implemented * by this library? Used to determine compatibility. */ -#define EXCHANGE_PROTOCOL_CURRENT 19 +#define EXCHANGE_PROTOCOL_CURRENT 21 /** * How many versions are we backwards compatible with? */ -#define EXCHANGE_PROTOCOL_AGE 2 +#define EXCHANGE_PROTOCOL_AGE 4 /** * Set to 1 for extra debug logging. @@ -758,6 +758,112 @@ denoms_cmp (const struct TALER_EXCHANGE_DenomPublicKey *denom1, /** + * Decode the JSON array in @a hard_limits from the /keys response + * and store the data in `hard_limits` array the @a key_data. + * + * @param[in] hard_limits JSON array to parse + * @param[out] key_data where to store the results we decoded + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + * (malformed JSON) + */ +static enum GNUNET_GenericReturnValue +parse_hard_limits (const json_t *hard_limits, + struct TALER_EXCHANGE_Keys *key_data) +{ + json_t *obj; + size_t off; + + key_data->hard_limits_length + = (unsigned int) json_array_size (hard_limits); + if ( ((size_t) key_data->hard_limits_length) + != json_array_size (hard_limits)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + key_data->hard_limits + = GNUNET_new_array (key_data->hard_limits_length, + struct TALER_EXCHANGE_AccountLimit); + + json_array_foreach (hard_limits, off, obj) + { + struct TALER_EXCHANGE_AccountLimit *al + = &key_data->hard_limits[off]; + struct GNUNET_JSON_Specification spec[] = { + TALER_JSON_spec_kycte ("operation_type", + &al->operation_type), + TALER_JSON_spec_amount_any ("threshold", + &al->threshold), + GNUNET_JSON_spec_relative_time ("timeframe", + &al->timeframe), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (obj, + spec, + NULL, NULL)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + } + return GNUNET_OK; +} + + +/** + * Decode the JSON array in @a zero_limits from the /keys response + * and store the data in `zero_limits` array the @a key_data. + * + * @param[in] zero_limits JSON array to parse + * @param[out] key_data where to store the results we decoded + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + * (malformed JSON) + */ +static enum GNUNET_GenericReturnValue +parse_zero_limits (const json_t *zero_limits, + struct TALER_EXCHANGE_Keys *key_data) +{ + json_t *obj; + size_t off; + + key_data->zero_limits_length + = (unsigned int) json_array_size (zero_limits); + if ( ((size_t) key_data->zero_limits_length) + != json_array_size (zero_limits)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + key_data->zero_limits + = GNUNET_new_array (key_data->zero_limits_length, + struct TALER_EXCHANGE_ZeroLimitedOperation); + + json_array_foreach (zero_limits, off, obj) + { + struct TALER_EXCHANGE_ZeroLimitedOperation *zol + = &key_data->zero_limits[off]; + struct GNUNET_JSON_Specification spec[] = { + TALER_JSON_spec_kycte ("operation_type", + &zol->operation_type), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (obj, + spec, + NULL, NULL)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + } + return GNUNET_OK; +} + + +/** * Decode the JSON in @a resp_obj from the /keys response * and store the data in the @a key_data. * @@ -920,6 +1026,8 @@ decode_keys_json (const json_t *resp_obj, EXITIF (1); } { + const json_t *hard_limits = NULL; + const json_t *zero_limits = NULL; struct GNUNET_JSON_Specification sspec[] = { TALER_JSON_spec_currency_specification ( "currency_specification", @@ -934,16 +1042,14 @@ decode_keys_json (const json_t *resp_obj, currency, &key_data->stefan_log), GNUNET_JSON_spec_mark_optional ( - TALER_JSON_spec_amount ( - "transaction_amount_limit", - currency, - &key_data->transaction_limit), + GNUNET_JSON_spec_array_const ( + "hard_limits", + &hard_limits), NULL), GNUNET_JSON_spec_mark_optional ( - TALER_JSON_spec_amount ( - "refund_amount_limit", - currency, - &key_data->refund_limit), + GNUNET_JSON_spec_array_const ( + "zero_limits", + &zero_limits), NULL), GNUNET_JSON_spec_double ( "stefan_lin", @@ -963,6 +1069,24 @@ decode_keys_json (const json_t *resp_obj, eline); EXITIF (1); } + if ( (NULL != hard_limits) && + (GNUNET_OK != + parse_hard_limits (hard_limits, + key_data)) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Parsing hard limits of /keys failed\n"); + EXITIF (1); + } + if ( (NULL != zero_limits) && + (GNUNET_OK != + parse_zero_limits (zero_limits, + key_data)) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Parsing hard limits of /keys failed\n"); + EXITIF (1); + } } key_data->currency = GNUNET_strdup (currency); @@ -1706,7 +1830,7 @@ TALER_EXCHANGE_get_keys ( ? last_date : NULL, NULL); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Requesting keys with URL `%s'.\n", gkh->url); eh = TALER_EXCHANGE_curl_easy_get_ (gkh->url); @@ -1903,6 +2027,12 @@ TALER_EXCHANGE_keys_decref (struct TALER_EXCHANGE_Keys *keys) 0); free_fees (keys->fees, keys->fees_len); + GNUNET_array_grow (keys->hard_limits, + keys->hard_limits_length, + 0); + GNUNET_array_grow (keys->zero_limits, + keys->zero_limits_length, + 0); json_decref (keys->extensions); GNUNET_free (keys->cspec.name); json_decref (keys->cspec.map_alt_unit_names); @@ -2118,6 +2248,8 @@ TALER_EXCHANGE_keys_to_json (const struct TALER_EXCHANGE_Keys *kd) json_t *accounts; json_t *global_fees; json_t *wblwk = NULL; + json_t *hard_limits; + json_t *zero_limits; now = GNUNET_TIME_timestamp_get (); signkeys = json_array (); @@ -2415,6 +2547,44 @@ TALER_EXCHANGE_keys_to_json (const struct TALER_EXCHANGE_Keys *kd) TALER_JSON_from_amount (a))); } + hard_limits = json_array (); + for (unsigned int i = 0; i < kd->hard_limits_length; i++) + { + const struct TALER_EXCHANGE_AccountLimit *al + = &kd->hard_limits[i]; + json_t *j; + + j = GNUNET_JSON_PACK ( + TALER_JSON_pack_amount ("threshold", + &al->threshold), + GNUNET_JSON_pack_time_rel ("timeframe", + al->timeframe), + TALER_JSON_pack_kycte ("operation_type", + al->operation_type) + ); + GNUNET_assert (0 == + json_array_append_new ( + hard_limits, + j)); + } + + zero_limits = json_array (); + for (unsigned int i = 0; i < kd->zero_limits_length; i++) + { + const struct TALER_EXCHANGE_ZeroLimitedOperation *zol + = &kd->zero_limits[i]; + json_t *j; + + j = GNUNET_JSON_PACK ( + TALER_JSON_pack_kycte ("operation_type", + zol->operation_type) + ); + GNUNET_assert (0 == + json_array_append_new ( + zero_limits, + j)); + } + keys = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("version", kd->version), @@ -2447,6 +2617,10 @@ TALER_EXCHANGE_keys_to_json (const struct TALER_EXCHANGE_Keys *kd) accounts), GNUNET_JSON_pack_array_steal ("wads", json_array ()), + GNUNET_JSON_pack_array_steal ("hard_limits", + hard_limits), + GNUNET_JSON_pack_array_steal ("zero_limits", + zero_limits), GNUNET_JSON_pack_array_steal ("denominations", denominations_by_group), GNUNET_JSON_pack_allow_null ( diff --git a/src/lib/exchange_api_kyc_check.c b/src/lib/exchange_api_kyc_check.c index 75f238cca..1231c7cc1 100644 --- a/src/lib/exchange_api_kyc_check.c +++ b/src/lib/exchange_api_kyc_check.c @@ -99,8 +99,10 @@ parse_account_status ( { struct TALER_EXCHANGE_AccountLimit *al = &ala[i]; struct GNUNET_JSON_Specification ispec[] = { - GNUNET_JSON_spec_bool ("soft_limit", - &al->soft_limit), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_bool ("soft_limit", + &al->soft_limit), + NULL), GNUNET_JSON_spec_relative_time ("timeframe", &al->timeframe), TALER_JSON_spec_kycte ("operation_type", @@ -110,6 +112,7 @@ parse_account_status ( GNUNET_JSON_spec_end () }; + al->soft_limit = false; if (GNUNET_OK != GNUNET_JSON_parse (limit, ispec, @@ -200,8 +203,28 @@ handle_kyc_check_finished (void *cls, (or API version conflict); just pass JSON reply to the application */ break; case MHD_HTTP_FORBIDDEN: - ks.hr.ec = TALER_JSON_get_error_code (j); - break; + { + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_fixed_auto ( + "expected_account_pub", + &ks.details.forbidden.expected_account_pub), + TALER_JSON_spec_ec ("code", + &ks.hr.ec), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (j, + spec, + NULL, NULL)) + { + GNUNET_break_op (0); + ks.hr.http_status = 0; + ks.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + break; + } + break; + } case MHD_HTTP_NOT_FOUND: ks.hr.ec = TALER_JSON_get_error_code (j); break; @@ -233,8 +256,9 @@ struct TALER_EXCHANGE_KycCheckHandle * TALER_EXCHANGE_kyc_check ( struct GNUNET_CURL_Context *ctx, const char *url, - uint64_t requirement_row, + const struct TALER_PaytoHashP *h_payto, const union TALER_AccountPrivateKeyP *account_priv, + enum TALER_EXCHANGE_KycLongPollTarget lpt, struct GNUNET_TIME_Relative timeout, TALER_EXCHANGE_KycStatusCallback cb, void *cb_cls) @@ -242,28 +266,49 @@ TALER_EXCHANGE_kyc_check ( struct TALER_EXCHANGE_KycCheckHandle *kch; CURL *eh; char arg_str[128]; + char timeout_ms[32]; + char lpt_str[32]; struct curl_slist *job_headers = NULL; unsigned long long tms; - tms = timeout.rel_value_us - / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us; - if (0 != tms) - GNUNET_snprintf (arg_str, - sizeof (arg_str), - "kyc-check/%llu?timeout_ms=%llu", - (unsigned long long) requirement_row, - tms); - else + { + char *hps; + + hps = GNUNET_STRINGS_data_to_string_alloc ( + h_payto, + sizeof (*h_payto)); GNUNET_snprintf (arg_str, sizeof (arg_str), - "kyc-check/%llu", - (unsigned long long) requirement_row); + "kyc-check/%s", + hps); + GNUNET_free (hps); + } + tms = timeout.rel_value_us + / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us; + GNUNET_snprintf (timeout_ms, + sizeof (timeout_ms), + "%llu", + tms); + GNUNET_snprintf (lpt_str, + sizeof (lpt_str), + "%d", + (int) lpt); kch = GNUNET_new (struct TALER_EXCHANGE_KycCheckHandle); kch->cb = cb; kch->cb_cls = cb_cls; - kch->url = TALER_url_join (url, - arg_str, - NULL); + kch->url + = TALER_url_join ( + url, + arg_str, + "timeout_ms", + GNUNET_TIME_relative_is_zero (timeout) + ? NULL + : timeout_ms, + "lpt", + TALER_EXCHANGE_KLPT_NONE == lpt + ? NULL + : lpt_str, + NULL); if (NULL == kch->url) { GNUNET_free (kch); @@ -284,8 +329,10 @@ TALER_EXCHANGE_kyc_check ( CURLOPT_TIMEOUT_MS, (long) (tms + 500L))); } - job_headers = curl_slist_append (job_headers, - "Content-Type: application/json"); + job_headers + = curl_slist_append ( + job_headers, + "Content-Type: application/json"); { union TALER_AccountSignatureP account_sig; char *sig_hdr; @@ -312,11 +359,12 @@ TALER_EXCHANGE_kyc_check ( return NULL; } } - kch->job = GNUNET_CURL_job_add2 (ctx, - eh, - job_headers, - &handle_kyc_check_finished, - kch); + kch->job + = GNUNET_CURL_job_add2 (ctx, + eh, + job_headers, + &handle_kyc_check_finished, + kch); curl_slist_free_all (job_headers); return kch; } diff --git a/src/lib/exchange_api_kyc_info.c b/src/lib/exchange_api_kyc_info.c index dc5823a33..073b5f4ba 100644 --- a/src/lib/exchange_api_kyc_info.c +++ b/src/lib/exchange_api_kyc_info.c @@ -245,6 +245,10 @@ handle_kyc_info_finished (void *cls, /* This should never happen, either us or the exchange is buggy (or API version conflict); just pass JSON reply to the application */ break; + case MHD_HTTP_FORBIDDEN: + lr.hr.ec = TALER_JSON_get_error_code (j); + lr.hr.hint = TALER_JSON_get_error_hint (j); + break; case MHD_HTTP_NOT_FOUND: lr.hr.ec = TALER_JSON_get_error_code (j); lr.hr.hint = TALER_JSON_get_error_hint (j); diff --git a/src/lib/exchange_api_lookup_aml_decisions.c b/src/lib/exchange_api_lookup_aml_decisions.c index 8d0d1f919..8f9b2c237 100644 --- a/src/lib/exchange_api_lookup_aml_decisions.c +++ b/src/lib/exchange_api_lookup_aml_decisions.c @@ -287,8 +287,10 @@ parse_aml_decisions ( &decision->h_payto), GNUNET_JSON_spec_uint64 ("rowid", &decision->rowid), - GNUNET_JSON_spec_string ("justification", - &decision->justification), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("justification", + &decision->justification), + NULL), GNUNET_JSON_spec_timestamp ("decision_time", &decision->decision_time), GNUNET_JSON_spec_mark_optional ( diff --git a/src/lib/exchange_api_lookup_kyc_attributes.c b/src/lib/exchange_api_lookup_kyc_attributes.c index dd19aefa6..6be04f4e4 100644 --- a/src/lib/exchange_api_lookup_kyc_attributes.c +++ b/src/lib/exchange_api_lookup_kyc_attributes.c @@ -277,13 +277,13 @@ TALER_EXCHANGE_lookup_kyc_attributes ( &officer_sig); { - char payto_s[sizeof (h_payto) * 2]; + char payto_s[sizeof (*h_payto) * 2]; char pub_str[sizeof (officer_pub) * 2]; char *end; end = GNUNET_STRINGS_data_to_string ( h_payto, - sizeof (h_payto), + sizeof (*h_payto), payto_s, sizeof (payto_s)); *end = '\0'; diff --git a/src/lib/exchange_api_management_get_keys.c b/src/lib/exchange_api_management_get_keys.c index b88ddc205..9ad59f3f8 100644 --- a/src/lib/exchange_api_management_get_keys.c +++ b/src/lib/exchange_api_management_get_keys.c @@ -176,7 +176,7 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh, struct TALER_EXCHANGE_FutureDenomPublicKey *denom_key = &fk->denom_keys[i]; const char *section_name; - struct GNUNET_JSON_Specification spec[] = { + struct GNUNET_JSON_Specification ispec[] = { TALER_JSON_spec_amount_any ("value", &denom_key->value), GNUNET_JSON_spec_timestamp ("stamp_start", @@ -206,7 +206,7 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh, if (GNUNET_OK != GNUNET_JSON_parse (j, - spec, + ispec, NULL, NULL)) { GNUNET_break_op (0); diff --git a/src/lib/exchange_api_restrictions.c b/src/lib/exchange_api_restrictions.c new file mode 100644 index 000000000..1b5bd0214 --- /dev/null +++ b/src/lib/exchange_api_restrictions.c @@ -0,0 +1,141 @@ +/* + 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 lib/exchange_api_restrictions.c + * @brief convenience functions related to account restrictions +a * @author Christian Grothoff + */ +#include "platform.h" +#include "taler_exchange_service.h" +#include <regex.h> + + +enum GNUNET_GenericReturnValue +TALER_EXCHANGE_test_account_allowed ( + const struct TALER_EXCHANGE_WireAccount *account, + bool check_credit, + const char *payto_uri) +{ + unsigned int limit + = check_credit + ? account->credit_restrictions_length + : account->debit_restrictions_length; + + /* check wire method matches */ + { + char *wm1; + char *wm2; + bool ok; + + wm1 = TALER_payto_get_method (payto_uri); + wm2 = TALER_payto_get_method (account->payto_uri); + ok = (0 == strcmp (wm1, + wm2)); + GNUNET_free (wm1); + GNUNET_free (wm2); + if (! ok) + return GNUNET_NO; + } + + for (unsigned int i = 0; i<limit; i++) + { + const struct TALER_EXCHANGE_AccountRestriction *ar + = check_credit + ? &account->credit_restrictions[i] + : &account->debit_restrictions[i]; + + switch (ar->type) + { + case TALER_EXCHANGE_AR_INVALID: + GNUNET_break (0); + return GNUNET_SYSERR; + case TALER_EXCHANGE_AR_DENY: + return GNUNET_NO; + case TALER_EXCHANGE_AR_REGEX: + { + regex_t ex; + bool allowed = false; + + if (0 != regcomp (&ex, + ar->details.regex.posix_egrep, + REG_NOSUB | REG_EXTENDED)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + if (regexec (&ex, + payto_uri, + 0, NULL, + REG_STARTEND)) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Account `%s' allowed by regex\n", + payto_uri); + allowed = true; + } + regfree (&ex); + if (! allowed) + return GNUNET_NO; + break; + } + } /* end switch */ + } /* end loop over restrictions */ + return GNUNET_YES; +} + + +void +TALER_EXCHANGE_keys_evaluate_hard_limits ( + const struct TALER_EXCHANGE_Keys *keys, + enum TALER_KYCLOGIC_KycTriggerEvent event, + struct TALER_Amount *limit) +{ + for (unsigned int i = 0; i<keys->hard_limits_length; i++) + { + const struct TALER_EXCHANGE_AccountLimit *al + = &keys->hard_limits[i]; + + if (event != al->operation_type) + continue; + if (al->soft_limit) + continue; + if (! TALER_amount_cmp_currency (limit, + &al->threshold)) + continue; + GNUNET_break (GNUNET_OK == + TALER_amount_min (limit, + limit, + &al->threshold)); + } +} + + +bool +TALER_EXCHANGE_keys_evaluate_zero_limits ( + const struct TALER_EXCHANGE_Keys *keys, + enum TALER_KYCLOGIC_KycTriggerEvent event) +{ + for (unsigned int i = 0; i<keys->zero_limits_length; i++) + { + const struct TALER_EXCHANGE_ZeroLimitedOperation *zlo + = &keys->zero_limits[i]; + + if (event == zlo->operation_type) + return true; + } + return false; +} diff --git a/src/lib/exchange_api_stefan.c b/src/lib/exchange_api_stefan.c index 226bca82f..92d419c03 100644 --- a/src/lib/exchange_api_stefan.c +++ b/src/lib/exchange_api_stefan.c @@ -125,7 +125,7 @@ TALER_EXCHANGE_keys_stefan_b2n ( min = get_unit (keys); if (NULL == min) return GNUNET_SYSERR; - if (1.0f <= keys->stefan_lin) + if (1.0 <= keys->stefan_lin) { /* This cannot work, linear STEFAN fee estimate always exceed any gross amount. */ @@ -273,7 +273,7 @@ TALER_EXCHANGE_keys_stefan_n2b ( min = get_unit (keys); if (NULL == min) return GNUNET_SYSERR; - if (1.0f <= keys->stefan_lin) + if (1.0 <= keys->stefan_lin) { /* This cannot work, linear STEFAN fee estimate always exceed any gross amount. */ diff --git a/src/mhd/mhd_legal.c b/src/mhd/mhd_legal.c index 9b80bf41b..df2c3f308 100644 --- a/src/mhd/mhd_legal.c +++ b/src/mhd/mhd_legal.c @@ -191,8 +191,8 @@ TALER_MHD_reply_legal (struct MHD_Connection *conn, /* Default terms of service if none are configured */ static struct Terms none = { .mime_type = "text/plain", - .terms = "not configured", - .language = "en", + .terms = (void *) "not configured", + .language = (void *) "en", .terms_size = strlen ("not configured") }; struct MHD_Response *resp; diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c index 9b0bd4c4e..2dd2582a2 100644 --- a/src/pq/pq_query_helper.c +++ b/src/pq/pq_query_helper.c @@ -668,14 +668,14 @@ qconv_array ( same_sized = (0 != meta->same_size); #define RETURN_UNLESS(cond) \ - do { \ - if (! (cond)) \ - { \ - GNUNET_break ((cond)); \ - noerror = false; \ - goto DONE; \ - } \ - } while (0) + do { \ + if (! (cond)) \ + { \ + GNUNET_break ((cond)); \ + noerror = false; \ + goto DONE; \ + } \ + } while (0) /* Calculate sizes and check bounds */ { diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c index 384200cfb..3d25d4c5b 100644 --- a/src/pq/pq_result_helper.c +++ b/src/pq/pq_result_helper.c @@ -1162,13 +1162,13 @@ extract_array_generic ( *((void **) dst) = NULL; #define FAIL_IF(cond) \ - do { \ - if ((cond)) \ - { \ - GNUNET_break (! (cond)); \ - goto FAIL; \ - } \ - } while (0) + do { \ + if ((cond)) \ + { \ + GNUNET_break (! (cond)); \ + goto FAIL; \ + } \ + } while (0) col_num = PQfnumber (result, fname); FAIL_IF (0 > col_num); @@ -1444,17 +1444,19 @@ TALER_PQ_result_spec_array_blinded_denom_sig ( GNUNET_PQ_get_oid_by_name (db, "bytea", &info->oid)); + { + struct GNUNET_PQ_ResultSpec res = { + .conv = extract_array_generic, + .cleaner = array_cleanup, + .dst = (void *) denom_sigs, + .fname = name, + .cls = info + }; + + return res; + } +} - struct GNUNET_PQ_ResultSpec res = { - .conv = extract_array_generic, - .cleaner = array_cleanup, - .dst = (void *) denom_sigs, - .fname = name, - .cls = info - }; - return res; - -}; struct GNUNET_PQ_ResultSpec TALER_PQ_result_spec_array_blinded_coin_hash ( @@ -1471,17 +1473,19 @@ TALER_PQ_result_spec_array_blinded_coin_hash ( GNUNET_PQ_get_oid_by_name (db, "bytea", &info->oid)); + { + struct GNUNET_PQ_ResultSpec res = { + .conv = extract_array_generic, + .cleaner = array_cleanup, + .dst = (void *) h_coin_evs, + .fname = name, + .cls = info + }; + + return res; + } +} - struct GNUNET_PQ_ResultSpec res = { - .conv = extract_array_generic, - .cleaner = array_cleanup, - .dst = (void *) h_coin_evs, - .fname = name, - .cls = info - }; - return res; - -}; struct GNUNET_PQ_ResultSpec TALER_PQ_result_spec_array_denom_hash ( @@ -1498,17 +1502,19 @@ TALER_PQ_result_spec_array_denom_hash ( GNUNET_PQ_get_oid_by_name (db, "bytea", &info->oid)); + { + struct GNUNET_PQ_ResultSpec res = { + .conv = extract_array_generic, + .cleaner = array_cleanup, + .dst = (void *) denom_hs, + .fname = name, + .cls = info + }; + + return res; + } +} - struct GNUNET_PQ_ResultSpec res = { - .conv = extract_array_generic, - .cleaner = array_cleanup, - .dst = (void *) denom_hs, - .fname = name, - .cls = info - }; - return res; - -}; struct GNUNET_PQ_ResultSpec TALER_PQ_result_spec_array_amount ( @@ -1535,15 +1541,17 @@ TALER_PQ_result_spec_array_amount ( currency, clen); } - - struct GNUNET_PQ_ResultSpec res = { - .conv = extract_array_generic, - .cleaner = array_cleanup, - .dst = (void *) amounts, - .fname = name, - .cls = info, - }; - return res; + { + struct GNUNET_PQ_ResultSpec res = { + .conv = extract_array_generic, + .cleaner = array_cleanup, + .dst = (void *) amounts, + .fname = name, + .cls = info, + }; + + return res; + } } @@ -1563,15 +1571,18 @@ TALER_PQ_result_spec_array_hash_code ( GNUNET_PQ_get_oid_by_name (db, "gnunet_hashcode", &info->oid)); - - struct GNUNET_PQ_ResultSpec res = { - .conv = extract_array_generic, - .cleaner = array_cleanup, - .dst = (void *) hashes, - .fname = name, - .cls = info, - }; - return res; + { + struct GNUNET_PQ_ResultSpec res = { + .conv = extract_array_generic, + .cleaner = array_cleanup, + .dst = (void *) hashes, + .fname = name, + .cls = info, + }; + + return res; + } } + /* end of pq_result_helper.c */ diff --git a/src/sq/sq_result_helper.c b/src/sq/sq_result_helper.c index 9d80837bd..b950ce926 100644 --- a/src/sq/sq_result_helper.c +++ b/src/sq/sq_result_helper.c @@ -47,6 +47,8 @@ extract_amount (void *cls, { struct TALER_Amount *amount = dst; const char *currency = cls; + uint64_t frac; + if ((sizeof (struct TALER_Amount) != *dst_size) || (SQLITE_INTEGER != sqlite3_column_type (result, (int) column)) || @@ -61,8 +63,8 @@ extract_amount (void *cls, TALER_CURRENCY_LEN); amount->value = (uint64_t) sqlite3_column_int64 (result, (int) column); - uint64_t frac = (uint64_t) sqlite3_column_int64 (result, - (int) column + 1); + frac = (uint64_t) sqlite3_column_int64 (result, + (int) column + 1); amount->fraction = (uint32_t) frac; return GNUNET_YES; } diff --git a/src/templating/mustach-tool.c b/src/templating/mustach-tool.c index 5f28c1f58..66ddc1f36 100644 --- a/src/templating/mustach-tool.c +++ b/src/templating/mustach-tool.c @@ -129,11 +129,12 @@ static char *readfile(const char *filename, size_t *length) static int load_json(const char *filename); static int process(const char *content, size_t length); -static void close_json(); +static void close_json(void); int main(int ac, char **av) { - char *t, *f; + char *t; + const char *f; char *prog = *av; int s; size_t length; diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am index 56e66451b..68bf4cd08 100644 --- a/src/testing/Makefile.am +++ b/src/testing/Makefile.am @@ -37,7 +37,7 @@ libtalertwistertesting_la_LDFLAGS = \ endif libtalertesting_la_LDFLAGS = \ - -version-info 1:0:0 \ + -version-info 2:0:1 \ -no-undefined libtalertesting_la_SOURCES = \ testing_api_cmd_age_withdraw.c \ diff --git a/src/testing/taler-unified-setup.sh b/src/testing/taler-unified-setup.sh index 770785bd5..86ec65b61 100755 --- a/src/testing/taler-unified-setup.sh +++ b/src/testing/taler-unified-setup.sh @@ -385,7 +385,7 @@ then echo "OK" echo -n "Set admin password..." AUSER="admin" - APASS="secret" + APASS="secret-password" libeufin-bank \ passwd \ -c "$CONF" \ @@ -450,13 +450,13 @@ STAGE="accounts" if [ "1" = "$START_FAKEBANK" ] then echo -n "Register Fakebank users ..." - register_fakebank_account fortytwo x - register_fakebank_account fortythree x - register_fakebank_account exchange x - register_fakebank_account tor x - register_fakebank_account gnunet x - register_fakebank_account tutorial x - register_fakebank_account survey x + register_fakebank_account fortytwo password + register_fakebank_account fortythree password + register_fakebank_account exchange password + register_fakebank_account tor password + register_fakebank_account gnunet password + register_fakebank_account tutorial password + register_fakebank_account survey password echo " DONE" fi @@ -467,13 +467,13 @@ then # the C helper for the add-incoming call. Without this value, # libeufin-bank won't find the target account to debit along a /add-incoming # call. - register_bank_account fortytwo x "User42" FR7630006000011234567890189 - register_bank_account fortythree x "Forty Three" - register_bank_account exchange x "Exchange Company" DE989651 - register_bank_account tor x "Tor Project" - register_bank_account gnunet x "GNUnet" - register_bank_account tutorial x "Tutorial" - register_bank_account survey x "Survey" + register_bank_account fortytwo password "User42" FR7630006000011234567890189 + register_bank_account fortythree password "Forty Three" + register_bank_account exchange password "Exchange Company" DE989651 + register_bank_account tor password "Tor Project" + register_bank_account gnunet password "GNUnet" + register_bank_account tutorial password "Tutorial" + register_bank_account survey password "Survey" echo " DONE" fi @@ -609,6 +609,12 @@ then taler-merchant-dbinit \ -c "$CONF" \ --reset &> taler-merchant-dbinit.log + $USE_VALGRIND taler-merchant-exchangekeyupdate \ + -c "$CONF" \ + -L "$LOGLEVEL" 2> taler-merchant-exchangekeyupdate.log & + $USE_VALGRIND taler-merchant-kyccheck \ + -c "$CONF" \ + -L "$LOGLEVEL" 2> taler-merchant-kyccheck.log & $USE_VALGRIND taler-merchant-httpd \ -c "$CONF" \ -L "$LOGLEVEL" 2> taler-merchant-httpd.log & @@ -817,7 +823,7 @@ do done if [ 1 != "$OK" ] then - exit_skip "Failed to launch (some) Taler services" + exit_skip "Failed to launch (some) Taler services (E: $E_DONE, M: $M_DONE, S: $S_DONE, K: $K_DONE, A: $A_DONE)" fi echo " OK" diff --git a/src/testing/test-taler-exchange-aggregator-postgres.conf b/src/testing/test-taler-exchange-aggregator-postgres.conf index 8c3ee4ba5..45789bd1c 100644 --- a/src/testing/test-taler-exchange-aggregator-postgres.conf +++ b/src/testing/test-taler-exchange-aggregator-postgres.conf @@ -47,13 +47,13 @@ ENABLE_CREDIT = YES WIRE_GATEWAY_URL = "http://localhost:8082/accounts/2/taler-wire-gateway/" WIRE_GATEWAY_AUTH_METHOD = basic USERNAME = Exchange -PASSWORD = x +PASSWORD = password [admin-accountcredentials-1] WIRE_GATEWAY_URL = "http://localhost:8082/accounts/2/taler-wire-gateway/" WIRE_GATEWAY_AUTH_METHOD = basic USERNAME = Exchange -PASSWORD = x +PASSWORD = password [bank] HTTP_PORT = 8082 diff --git a/src/testing/test-taler-exchange-wirewatch-postgres.conf b/src/testing/test-taler-exchange-wirewatch-postgres.conf index 4f13077ac..96b3121ab 100644 --- a/src/testing/test-taler-exchange-wirewatch-postgres.conf +++ b/src/testing/test-taler-exchange-wirewatch-postgres.conf @@ -46,13 +46,13 @@ ENABLE_CREDIT = YES WIRE_GATEWAY_URL = "http://localhost:8082/accounts/2/taler-wire-gateway/" WIRE_GATEWAY_AUTH_METHOD = basic USERNAME = Exchange -PASSWORD = x +PASSWORD = password [admin-accountcredentials-1] WIRE_GATEWAY_URL = "http://localhost:8082/accounts/2/taler-wire-gateway/" WIRE_GATEWAY_AUTH_METHOD = basic USERNAME = Exchange -PASSWORD = x +PASSWORD = password [bank] HTTP_PORT = 8082 @@ -66,6 +66,7 @@ REGISTRATION_BONUS = EUR:100 SUGGESTED_WITHDRAWAL_EXCHANGE = http://localhost:8081/ SERVE = tcp PORT = 8082 +PWD_HASH_CONFIG = { "cost": 4 } # Need at least one coin, otherwise Exchange # refuses to start. diff --git a/src/testing/test_bank_api.conf b/src/testing/test_bank_api.conf index c262ae197..7e0543e6d 100644 --- a/src/testing/test_bank_api.conf +++ b/src/testing/test_bank_api.conf @@ -21,3 +21,4 @@ REGISTRATION_BONUS = EUR:100 SUGGESTED_WITHDRAWAL_EXCHANGE = http://localhost:8081/ SERVE = tcp PORT = 8082 +PWD_HASH_CONFIG = { "cost": 4 } diff --git a/src/testing/test_bank_api_fakebank.conf b/src/testing/test_bank_api_fakebank.conf index 62fa4cd4c..c387a0a09 100644 --- a/src/testing/test_bank_api_fakebank.conf +++ b/src/testing/test_bank_api_fakebank.conf @@ -11,11 +11,11 @@ PAYTO_URI = "payto://x-taler-bank/localhost:8082/2?receiver-name=2" WIRE_GATEWAY_URL = "http://localhost:8082/accounts/2/taler-wire-gateway/" WIRE_GATEWAY_AUTH_METHOD = basic USERNAME = Exchange -PASSWORD = x +PASSWORD = password [admin-accountcredentials-2] WIRE_GATEWAY_URL = "http://localhost:8082/accounts/2/taler-wire-gateway/" WIRE_GATEWAY_AUTH_METHOD = basic # For now, fakebank still checks against the Exchange account... USERNAME = Exchange -PASSWORD = x +PASSWORD = password diff --git a/src/testing/test_bank_api_nexus.conf b/src/testing/test_bank_api_nexus.conf index 605c7b00e..b2ce98d08 100644 --- a/src/testing/test_bank_api_nexus.conf +++ b/src/testing/test_bank_api_nexus.conf @@ -8,14 +8,14 @@ PAYTO_URI = payto://iban/BIC/ES9121000418450200051332?receiver-name=Exchange WIRE_GATEWAY_URL = http://localhost:8082/accounts/exchange/taler-wire-gateway/ WIRE_GATEWAY_AUTH_METHOD = basic USERNAME = exchange -PASSWORD = x +PASSWORD = password [admin-accountcredentials-2] WIRE_GATEWAY_URL = http://localhost:8082/accounts/exchange/taler-wire-gateway/ WIRE_GATEWAY_AUTH_METHOD = basic USERNAME = admin # 'secret' is from taler-unified-setup.sh -PASSWORD = secret +PASSWORD = secret-password [libeufin-bankdb-postgres] CONFIG="postgresql:///talercheck" diff --git a/src/testing/test_exchange_api.c b/src/testing/test_exchange_api.c index 533995b37..964e7e8ef 100644 --- a/src/testing/test_exchange_api.c +++ b/src/testing/test_exchange_api.c @@ -179,22 +179,40 @@ run (void *cls, /** * Spend the coin. */ - TALER_TESTING_cmd_deposit ("deposit-simple", - "withdraw-coin-1", - 0, - cred.user42_payto, - "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}", - GNUNET_TIME_UNIT_ZERO, - "EUR:5", - MHD_HTTP_OK), - TALER_TESTING_cmd_deposit_replay ("deposit-simple-replay-1", - "deposit-simple", - MHD_HTTP_OK), - TALER_TESTING_cmd_sleep ("sleep-before-deposit-replay", - 1), - TALER_TESTING_cmd_deposit_replay ("deposit-simple-replay-2", - "deposit-simple", - MHD_HTTP_OK), + TALER_TESTING_cmd_set_var ( + "account-priv", + TALER_TESTING_cmd_deposit ( + "deposit-simple-fail-kyc", + "withdraw-coin-1", + 0, + cred.user42_payto, + "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:5", + MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS)), + TALER_TESTING_cmd_admin_add_kycauth ( + "kyc-auth-transfer", + "EUR:0.01", + &cred.ba, + cred.user42_payto, + "deposit-simple-fail-kyc"), + CMD_EXEC_WIREWATCH ( + "import-kyc-account-withdraw"), + TALER_TESTING_cmd_deposit_replay ( + "deposit-simple", + "deposit-simple-fail-kyc", + MHD_HTTP_OK), + TALER_TESTING_cmd_deposit_replay ( + "deposit-simple-replay-1", + "deposit-simple", + MHD_HTTP_OK), + TALER_TESTING_cmd_sleep ( + "sleep-before-deposit-replay", + 1), + TALER_TESTING_cmd_deposit_replay ( + "deposit-simple-replay-2", + "deposit-simple", + MHD_HTTP_OK), /* This creates a conflict, as we have the same coin public key (reuse!), but different denomination public keys (which is not allowed). However, note that this does NOT work with 'CS', as for a different @@ -202,52 +220,64 @@ run (void *cls, thus will generate a different coin private key as R0/R1 are hashed into the coin priv. So here, we fail to 'reuse' the key due to the cryptographic construction! */ - TALER_TESTING_cmd_deposit ("deposit-reused-coin-key-failure", - "withdraw-coin-1x", - 0, - cred.user42_payto, - "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}", - GNUNET_TIME_UNIT_ZERO, - "EUR:1", - uses_cs - ? MHD_HTTP_OK - : MHD_HTTP_CONFLICT), + TALER_TESTING_cmd_deposit ( + "deposit-reused-coin-key-failure", + "withdraw-coin-1x", + 0, + cred.user42_payto, + "{\"items\":[{\"name\":\"conflicting ice cream\",\"value\":1}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:1", + uses_cs + ? MHD_HTTP_OK + : MHD_HTTP_CONFLICT), /** * Try to double spend using different wire details. */ - TALER_TESTING_cmd_deposit ("deposit-double-1", - "withdraw-coin-1", - 0, - cred.user43_payto, - "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}", - GNUNET_TIME_UNIT_ZERO, - "EUR:5", - MHD_HTTP_CONFLICT), + TALER_TESTING_cmd_admin_add_kycauth ( + "kyc-auth-transfer-2", + "EUR:0.01", + &cred.ba, + cred.user43_payto, + "deposit-simple-fail-kyc"), + CMD_EXEC_WIREWATCH ( + "import-kyc-account-1"), + TALER_TESTING_cmd_deposit ( + "deposit-double-1", + "withdraw-coin-1", + 0, + cred.user43_payto, + "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:5", + MHD_HTTP_CONFLICT), /* Try to double spend using a different transaction id. * The test needs the contract terms to differ. This * is currently the case because of the "timestamp" field, * which is set automatically by #TALER_TESTING_cmd_deposit(). * This could theoretically fail if at some point a deposit - * command executes in less than 1 ms. */// - TALER_TESTING_cmd_deposit ("deposit-double-1", - "withdraw-coin-1", - 0, - cred.user43_payto, - "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}", - GNUNET_TIME_UNIT_ZERO, - "EUR:5", - MHD_HTTP_CONFLICT), + * command executes in less than 1 ms. */ + TALER_TESTING_cmd_deposit ( + "deposit-double-1", + "withdraw-coin-1", + 0, + cred.user43_payto, + "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:5", + MHD_HTTP_CONFLICT), /** * Try to double spend with different proposal. */ - TALER_TESTING_cmd_deposit ("deposit-double-2", - "withdraw-coin-1", - 0, - cred.user43_payto, - "{\"items\":[{\"name\":\"ice cream\",\"value\":2}]}", - GNUNET_TIME_UNIT_ZERO, - "EUR:5", - MHD_HTTP_CONFLICT), + TALER_TESTING_cmd_deposit ( + "deposit-double-2", + "withdraw-coin-1", + 0, + cred.user43_payto, + "{\"items\":[{\"name\":\"ice cream\",\"value\":2}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:5", + MHD_HTTP_CONFLICT), TALER_TESTING_cmd_end () }; @@ -258,19 +288,22 @@ run (void *cls, * with MHD_HTTP_CONFLICT, but for a different reason: here it * is not a denomination conflict, but a double-spending conflict. */ - TALER_TESTING_cmd_melt ("refresh-melt-reused-coin-key-failure", - "withdraw-coin-1x", - MHD_HTTP_CONFLICT, - NULL), + TALER_TESTING_cmd_melt ( + "refresh-melt-reused-coin-key-failure", + "withdraw-coin-1x", + MHD_HTTP_CONFLICT, + NULL), /* Fill reserve with EUR:5, 1ct is for fees. */ - CMD_TRANSFER_TO_EXCHANGE ("refresh-create-reserve-1", - "EUR:5.01"), - TALER_TESTING_cmd_check_bank_admin_transfer ("ck-refresh-create-reserve-1", - "EUR:5.01", - cred.user42_payto, - cred.exchange_payto, - "refresh-create-reserve-1"), + CMD_TRANSFER_TO_EXCHANGE ( + "refresh-create-reserve-1", + "EUR:5.01"), + TALER_TESTING_cmd_check_bank_admin_transfer ( + "ck-refresh-create-reserve-1", + "EUR:5.01", + cred.user42_payto, + cred.exchange_payto, + "refresh-create-reserve-1"), /** * Make previous command effective. */ @@ -278,83 +311,93 @@ run (void *cls, /** * Withdraw EUR:5. */ - TALER_TESTING_cmd_withdraw_amount ("refresh-withdraw-coin-1", - "refresh-create-reserve-1", - "EUR:5", - 0, /* age restriction off */ - MHD_HTTP_OK), + TALER_TESTING_cmd_withdraw_amount ( + "refresh-withdraw-coin-1", + "refresh-create-reserve-1", + "EUR:5", + 0, /* age restriction off */ + MHD_HTTP_OK), /* Try to partially spend (deposit) 1 EUR of the 5 EUR coin * (in full) (merchant would receive EUR:0.99 due to 1 ct * deposit fee) */ - TALER_TESTING_cmd_deposit ("refresh-deposit-partial", - "refresh-withdraw-coin-1", - 0, - cred.user42_payto, - "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:1\"}]}", - GNUNET_TIME_UNIT_ZERO, - "EUR:1", - MHD_HTTP_OK), + TALER_TESTING_cmd_deposit ( + "refresh-deposit-partial", + "refresh-withdraw-coin-1", + 0, + cred.user42_payto, + "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:1\"}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:1", + MHD_HTTP_OK), /** * Melt the rest of the coin's value * (EUR:4.00 = 3x EUR:1.03 + 7x EUR:0.13) */ - TALER_TESTING_cmd_melt_double ("refresh-melt-1", - "refresh-withdraw-coin-1", - MHD_HTTP_OK, - NULL), + TALER_TESTING_cmd_melt_double ( + "refresh-melt-1", + "refresh-withdraw-coin-1", + MHD_HTTP_OK, + NULL), /** * Complete (successful) melt operation, and * withdraw the coins */ - TALER_TESTING_cmd_refresh_reveal ("refresh-reveal-1", - "refresh-melt-1", - MHD_HTTP_OK), + TALER_TESTING_cmd_refresh_reveal ( + "refresh-reveal-1", + "refresh-melt-1", + MHD_HTTP_OK), /** * Do it again to check idempotency */ - TALER_TESTING_cmd_refresh_reveal ("refresh-reveal-1-idempotency", - "refresh-melt-1", - MHD_HTTP_OK), + TALER_TESTING_cmd_refresh_reveal ( + "refresh-reveal-1-idempotency", + "refresh-melt-1", + MHD_HTTP_OK), /** * Test that /refresh/link works */ - TALER_TESTING_cmd_refresh_link ("refresh-link-1", - "refresh-reveal-1", - MHD_HTTP_OK), + TALER_TESTING_cmd_refresh_link ( + "refresh-link-1", + "refresh-reveal-1", + MHD_HTTP_OK), /** * Try to spend a refreshed EUR:1 coin */ - TALER_TESTING_cmd_deposit ("refresh-deposit-refreshed-1a", - "refresh-reveal-1-idempotency", - 0, - cred.user42_payto, - "{\"items\":[{\"name\":\"ice cream\",\"value\":3}]}", - GNUNET_TIME_UNIT_ZERO, - "EUR:1", - MHD_HTTP_OK), + TALER_TESTING_cmd_deposit ( + "refresh-deposit-refreshed-1a", + "refresh-reveal-1-idempotency", + 0, + cred.user42_payto, + "{\"items\":[{\"name\":\"ice cream\",\"value\":3}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:1", + MHD_HTTP_OK), /** * Try to spend a refreshed EUR:0.1 coin */ - TALER_TESTING_cmd_deposit ("refresh-deposit-refreshed-1b", - "refresh-reveal-1", - 3, - cred.user43_payto, - "{\"items\":[{\"name\":\"ice cream\",\"value\":3}]}", - GNUNET_TIME_UNIT_ZERO, - "EUR:0.1", - MHD_HTTP_OK), + TALER_TESTING_cmd_deposit ( + "refresh-deposit-refreshed-1b", + "refresh-reveal-1", + 3, + cred.user43_payto, + "{\"items\":[{\"name\":\"cheap ice cream\",\"value\":3}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:0.1", + MHD_HTTP_OK), /* Test running a failing melt operation (same operation * again must fail) */ - TALER_TESTING_cmd_melt ("refresh-melt-failing", - "refresh-withdraw-coin-1", - MHD_HTTP_CONFLICT, - NULL), + TALER_TESTING_cmd_melt ( + "refresh-melt-failing", + "refresh-withdraw-coin-1", + MHD_HTTP_CONFLICT, + NULL), /* Test running a failing melt operation (on a coin that was itself revealed and subsequently deposited) */ - TALER_TESTING_cmd_melt ("refresh-melt-failing-2", - "refresh-reveal-1", - MHD_HTTP_CONFLICT, - NULL), + TALER_TESTING_cmd_melt ( + "refresh-melt-failing-2", + "refresh-reveal-1", + MHD_HTTP_CONFLICT, + NULL), TALER_TESTING_cmd_end () }; @@ -372,13 +415,15 @@ run (void *cls, /** * Move money to the exchange's bank account. */ - CMD_TRANSFER_TO_EXCHANGE ("create-reserve-age", - "EUR:6.01"), - TALER_TESTING_cmd_check_bank_admin_transfer ("check-create-reserve-age", - "EUR:6.01", - cred.user42_payto, - cred.exchange_payto, - "create-reserve-age"), + CMD_TRANSFER_TO_EXCHANGE ( + "create-reserve-age", + "EUR:6.01"), + TALER_TESTING_cmd_check_bank_admin_transfer ( + "check-create-reserve-age", + "EUR:6.01", + cred.user42_payto, + cred.exchange_payto, + "create-reserve-age"), /** * Make a reserve exist, according to the previous * transfer. @@ -387,11 +432,12 @@ run (void *cls, /** * Withdraw EUR:5. */ - TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-age-1", - "create-reserve-age", - "EUR:5", - 13, - MHD_HTTP_OK), + TALER_TESTING_cmd_withdraw_amount ( + "withdraw-coin-age-1", + "create-reserve-age", + "EUR:5", + 13, + MHD_HTTP_OK), TALER_TESTING_cmd_end () }; @@ -400,25 +446,30 @@ run (void *cls, /** * Spend the coin. */ - TALER_TESTING_cmd_deposit ("deposit-simple-age", - "withdraw-coin-age-1", - 0, - cred.user42_payto, - "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}", - GNUNET_TIME_UNIT_ZERO, - "EUR:4.99", - MHD_HTTP_OK), - TALER_TESTING_cmd_deposit_replay ("deposit-simple-replay-age", - "deposit-simple-age", - MHD_HTTP_OK), - TALER_TESTING_cmd_deposit_replay ("deposit-simple-replay-age-1", - "deposit-simple-age", - MHD_HTTP_OK), - TALER_TESTING_cmd_sleep ("sleep-before-age-deposit-replay", - 1), - TALER_TESTING_cmd_deposit_replay ("deposit-simple-replay-age-2", - "deposit-simple-age", - MHD_HTTP_OK), + TALER_TESTING_cmd_deposit ( + "deposit-simple-age", + "withdraw-coin-age-1", + 0, + cred.user42_payto, + "{\"items\":[{\"name\":\"unique ice cream\",\"value\":1}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:4.99", + MHD_HTTP_OK), + TALER_TESTING_cmd_deposit_replay ( + "deposit-simple-replay-age", + "deposit-simple-age", + MHD_HTTP_OK), + TALER_TESTING_cmd_deposit_replay ( + "deposit-simple-replay-age-1", + "deposit-simple-age", + MHD_HTTP_OK), + TALER_TESTING_cmd_sleep ( + "sleep-before-age-deposit-replay", + 1), + TALER_TESTING_cmd_deposit_replay ( + "deposit-simple-replay-age-2", + "deposit-simple-age", + MHD_HTTP_OK), TALER_TESTING_cmd_end () }; @@ -427,102 +478,68 @@ run (void *cls, * execution of transactions, the answer should be that * the exchange knows about the deposit, but has no WTID yet. */ - TALER_TESTING_cmd_deposits_get ("deposit-wtid-found", - "deposit-simple", - 0, - MHD_HTTP_ACCEPTED, - NULL), + TALER_TESTING_cmd_deposits_get ( + "deposit-wtid-found", + "deposit-simple", + 0, + MHD_HTTP_ACCEPTED, + NULL), /* Try resolving a deposit's WTID for a failed deposit. * As the deposit failed, the answer should be that the * exchange does NOT know about the deposit. */ - TALER_TESTING_cmd_deposits_get ("deposit-wtid-failing", - "deposit-double-2", - 0, - MHD_HTTP_NOT_FOUND, - NULL), + TALER_TESTING_cmd_deposits_get ( + "deposit-wtid-failing", + "deposit-double-2", + 0, + MHD_HTTP_NOT_FOUND, + NULL), /* Try resolving an undefined (all zeros) WTID; this * should fail as obviously the exchange didn't use that * WTID value for any transaction. */ - TALER_TESTING_cmd_track_transfer_empty ("wire-deposit-failing", - NULL, - MHD_HTTP_NOT_FOUND), - /* Run transfers. Note that _actual_ aggregation will NOT - * happen here, as each deposit operation is run with a - * fresh merchant public key, so the aggregator will treat - * them as "different" merchants and do the wire transfers - * individually. */ + TALER_TESTING_cmd_track_transfer_empty ( + "wire-deposit-failing", + NULL, + MHD_HTTP_NOT_FOUND), + /* Run transfers. */ CMD_EXEC_AGGREGATOR ("run-aggregator"), /** * Check all the transfers took place. */ - TALER_TESTING_cmd_check_bank_transfer ("check_bank_transfer-499c", - cred.exchange_url, - "EUR:4.98", - cred.exchange_payto, - cred.user42_payto), - TALER_TESTING_cmd_check_bank_transfer ("check_bank_transfer-499c2", - cred.exchange_url, - "EUR:4.97", - cred.exchange_payto, - cred.user42_payto), - TALER_TESTING_cmd_check_bank_transfer ("check_bank_transfer-99c1", - cred.exchange_url, - "EUR:0.98", - cred.exchange_payto, - cred.user42_payto), - TALER_TESTING_cmd_check_bank_transfer ("check_bank_transfer-99c2", - cred.exchange_url, - "EUR:0.98", - cred.exchange_payto, - cred.user42_payto), - TALER_TESTING_cmd_check_bank_transfer ("check_bank_transfer-99c3", - cred.exchange_url, - "EUR:0.98", - cred.exchange_payto, - cred.user42_payto), - TALER_TESTING_cmd_check_bank_transfer ("check_bank_transfer-99c4", - cred.exchange_url, - "EUR:0.98", - cred.exchange_payto, - cred.user42_payto), - TALER_TESTING_cmd_check_bank_transfer ("check_bank_transfer-08c", - cred.exchange_url, - "EUR:0.08", - cred.exchange_payto, - cred.user43_payto), - TALER_TESTING_cmd_check_bank_transfer ("check_bank_transfer-08c2", - cred.exchange_url, - "EUR:0.08", - cred.exchange_payto, - cred.user43_payto), - /* In case of CS, one transaction above succeeded that - failed for RSA, hence we need to check for an extra transfer here */ - uses_cs - ? TALER_TESTING_cmd_check_bank_transfer ("check_bank_transfer-98c", - cred.exchange_url, - "EUR:0.98", - cred.exchange_payto, - cred.user42_payto) - : TALER_TESTING_cmd_sleep ("dummy", - 0), + TALER_TESTING_cmd_check_bank_transfer ( + "check_bank_transfer-42-aggregate", + cred.exchange_url, + /* In case of CS, one transaction above succeeded that + failed for RSA, hence we get a larger amount here */ + uses_cs ? "EUR:14.91" : "EUR:13.92", + cred.exchange_payto, + cred.user42_payto), + TALER_TESTING_cmd_check_bank_transfer ( + "check_bank_transfer-43-aggregate", + cred.exchange_url, + "EUR:0.17", + cred.exchange_payto, + cred.user43_payto), TALER_TESTING_cmd_check_bank_empty ("check_bank_empty"), - TALER_TESTING_cmd_deposits_get ("deposit-wtid-ok", - "deposit-simple", - 0, - MHD_HTTP_OK, - "check_bank_transfer-499c"), - TALER_TESTING_cmd_track_transfer ("wire-deposit-success-bank", - "check_bank_transfer-99c1", - MHD_HTTP_OK, - "EUR:0.98", - "EUR:0.01"), - TALER_TESTING_cmd_track_transfer ("wire-deposits-success-wtid", - "deposit-wtid-ok", - MHD_HTTP_OK, - "EUR:4.98", - "EUR:0.01"), + TALER_TESTING_cmd_deposits_get ( + "deposit-wtid-ok", + "deposit-simple", + 0, + MHD_HTTP_OK, + "check_bank_transfer-42-aggregate"), + TALER_TESTING_cmd_track_transfer ( + "wire-deposit-success-bank", + "check_bank_transfer-42-aggregate", + MHD_HTTP_OK, + uses_cs ? "EUR:14.91" : "EUR:13.92", + "EUR:0.01"), + TALER_TESTING_cmd_track_transfer ( + "wire-deposits-success-wtid", + "check_bank_transfer-43-aggregate", + MHD_HTTP_OK, + "EUR:0.17", + "EUR:0.01"), TALER_TESTING_cmd_end () }; @@ -532,8 +549,9 @@ run (void *cls, */ struct TALER_TESTING_Command unaggregation[] = { TALER_TESTING_cmd_check_bank_empty ("far-future-aggregation-a"), - CMD_TRANSFER_TO_EXCHANGE ("create-reserve-unaggregated", - "EUR:5.01"), + CMD_TRANSFER_TO_EXCHANGE ( + "create-reserve-unaggregated", + "EUR:5.01"), /* "consume" reserve creation transfer. */ TALER_TESTING_cmd_check_bank_admin_transfer ( "check-create-reserve-unaggregated", @@ -542,21 +560,23 @@ run (void *cls, cred.exchange_payto, "create-reserve-unaggregated"), CMD_EXEC_WIREWATCH ("wirewatch-unaggregated"), - TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-unaggregated", - "create-reserve-unaggregated", - "EUR:5", - 0, /* age restriction off */ - MHD_HTTP_OK), - TALER_TESTING_cmd_deposit ("deposit-unaggregated", - "withdraw-coin-unaggregated", - 0, - cred.user43_payto, - "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}", - GNUNET_TIME_relative_multiply ( - GNUNET_TIME_UNIT_YEARS, - 3000), - "EUR:5", - MHD_HTTP_OK), + TALER_TESTING_cmd_withdraw_amount ( + "withdraw-coin-unaggregated", + "create-reserve-unaggregated", + "EUR:5", + 0, /* age restriction off */ + MHD_HTTP_OK), + TALER_TESTING_cmd_deposit ( + "deposit-unaggregated", + "withdraw-coin-unaggregated", + 0, + cred.user43_payto, + "{\"items\":[{\"name\":\"different ice cream\",\"value\":1}]}", + GNUNET_TIME_relative_multiply ( + GNUNET_TIME_UNIT_YEARS, + 3000), + "EUR:5", + MHD_HTTP_OK), CMD_EXEC_AGGREGATOR ("aggregation-attempt"), TALER_TESTING_cmd_check_bank_empty ( @@ -567,8 +587,9 @@ run (void *cls, struct TALER_TESTING_Command refresh_age[] = { /* Fill reserve with EUR:5, 1ct is for fees. */ - CMD_TRANSFER_TO_EXCHANGE ("refresh-create-reserve-age-1", - "EUR:6.01"), + CMD_TRANSFER_TO_EXCHANGE ( + "refresh-create-reserve-age-1", + "EUR:6.01"), TALER_TESTING_cmd_check_bank_admin_transfer ( "ck-refresh-create-reserve-age-1", "EUR:6.01", @@ -582,83 +603,93 @@ run (void *cls, /** * Withdraw EUR:7 with age restriction for age 13. */ - TALER_TESTING_cmd_withdraw_amount ("refresh-withdraw-coin-age-1", - "refresh-create-reserve-age-1", - "EUR:5", - 13, - MHD_HTTP_OK), + TALER_TESTING_cmd_withdraw_amount ( + "refresh-withdraw-coin-age-1", + "refresh-create-reserve-age-1", + "EUR:5", + 13, + MHD_HTTP_OK), /* Try to partially spend (deposit) 1 EUR of the 5 EUR coin * (in full) (merchant would receive EUR:0.99 due to 1 ct * deposit fee) */ - TALER_TESTING_cmd_deposit ("refresh-deposit-partial-age", - "refresh-withdraw-coin-age-1", - 0, - cred.user42_payto, - "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:1\"}]}", - GNUNET_TIME_UNIT_ZERO, - "EUR:1", - MHD_HTTP_OK), + TALER_TESTING_cmd_deposit ( + "refresh-deposit-partial-age", + "refresh-withdraw-coin-age-1", + 0, + cred.user42_payto, + "{\"items\":[{\"name\":\"special ice cream\",\"value\":\"EUR:1\"}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:1", + MHD_HTTP_OK), /** * Melt the rest of the coin's value * (EUR:4.00 = 3x EUR:1.03 + 7x EUR:0.13) */ - TALER_TESTING_cmd_melt_double ("refresh-melt-age-1", - "refresh-withdraw-coin-age-1", - MHD_HTTP_OK, - NULL), + TALER_TESTING_cmd_melt_double ( + "refresh-melt-age-1", + "refresh-withdraw-coin-age-1", + MHD_HTTP_OK, + NULL), /** * Complete (successful) melt operation, and * withdraw the coins */ - TALER_TESTING_cmd_refresh_reveal ("refresh-reveal-age-1", - "refresh-melt-age-1", - MHD_HTTP_OK), + TALER_TESTING_cmd_refresh_reveal ( + "refresh-reveal-age-1", + "refresh-melt-age-1", + MHD_HTTP_OK), /** * Do it again to check idempotency */ - TALER_TESTING_cmd_refresh_reveal ("refresh-reveal-age-1-idempotency", - "refresh-melt-age-1", - MHD_HTTP_OK), + TALER_TESTING_cmd_refresh_reveal ( + "refresh-reveal-age-1-idempotency", + "refresh-melt-age-1", + MHD_HTTP_OK), /** * Test that /refresh/link works */ - TALER_TESTING_cmd_refresh_link ("refresh-link-age-1", - "refresh-reveal-age-1", - MHD_HTTP_OK), + TALER_TESTING_cmd_refresh_link ( + "refresh-link-age-1", + "refresh-reveal-age-1", + MHD_HTTP_OK), /** * Try to spend a refreshed EUR:1 coin */ - TALER_TESTING_cmd_deposit ("refresh-deposit-refreshed-age-1a", - "refresh-reveal-age-1-idempotency", - 0, - cred.user42_payto, - "{\"items\":[{\"name\":\"ice cream\",\"value\":3}]}", - GNUNET_TIME_UNIT_ZERO, - "EUR:1", - MHD_HTTP_OK), + TALER_TESTING_cmd_deposit ( + "refresh-deposit-refreshed-age-1a", + "refresh-reveal-age-1-idempotency", + 0, + cred.user42_payto, + "{\"items\":[{\"name\":\"garlic ice cream\",\"value\":3}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:1", + MHD_HTTP_OK), /** * Try to spend a refreshed EUR:0.1 coin */ - TALER_TESTING_cmd_deposit ("refresh-deposit-refreshed-age-1b", - "refresh-reveal-age-1", - 3, - cred.user43_payto, - "{\"items\":[{\"name\":\"ice cream\",\"value\":3}]}", - GNUNET_TIME_UNIT_ZERO, - "EUR:0.1", - MHD_HTTP_OK), + TALER_TESTING_cmd_deposit ( + "refresh-deposit-refreshed-age-1b", + "refresh-reveal-age-1", + 3, + cred.user43_payto, + "{\"items\":[{\"name\":\"spicy ice cream\",\"value\":3}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:0.1", + MHD_HTTP_OK), /* Test running a failing melt operation (same operation * again must fail) */ - TALER_TESTING_cmd_melt ("refresh-melt-failing-age", - "refresh-withdraw-coin-age-1", - MHD_HTTP_CONFLICT, - NULL), + TALER_TESTING_cmd_melt ( + "refresh-melt-failing-age", + "refresh-withdraw-coin-age-1", + MHD_HTTP_CONFLICT, + NULL), /* Test running a failing melt operation (on a coin that was itself revealed and subsequently deposited) */ - TALER_TESTING_cmd_melt ("refresh-melt-failing-age-2", - "refresh-reveal-age-1", - MHD_HTTP_CONFLICT, - NULL), + TALER_TESTING_cmd_melt ( + "refresh-melt-failing-age-2", + "refresh-reveal-age-1", + MHD_HTTP_CONFLICT, + NULL), TALER_TESTING_cmd_end () }; @@ -677,34 +708,38 @@ run (void *cls, cred.exchange_payto, "create-reserve-aggtest"), CMD_EXEC_WIREWATCH ("wirewatch-aggtest"), - TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-aggtest", - "create-reserve-aggtest", - "EUR:5", - 0, /* age restriction off */ - MHD_HTTP_OK), - TALER_TESTING_cmd_deposit ("deposit-aggtest-1", - "withdraw-coin-aggtest", - 0, - cred.user43_payto, - "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}", - GNUNET_TIME_UNIT_ZERO, - "EUR:2", - MHD_HTTP_OK), - TALER_TESTING_cmd_deposit_with_ref ("deposit-aggtest-2", - "withdraw-coin-aggtest", - 0, - cred.user43_payto, - "{\"items\":[{\"name\":\"foo bar\",\"value\":1}]}", - GNUNET_TIME_UNIT_ZERO, - "EUR:2", - MHD_HTTP_OK, - "deposit-aggtest-1"), + TALER_TESTING_cmd_withdraw_amount ( + "withdraw-coin-aggtest", + "create-reserve-aggtest", + "EUR:5", + 0, /* age restriction off */ + MHD_HTTP_OK), + TALER_TESTING_cmd_deposit ( + "deposit-aggtest-1", + "withdraw-coin-aggtest", + 0, + cred.user43_payto, + "{\"items\":[{\"name\":\"cinamon ice cream\",\"value\":1}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:2", + MHD_HTTP_OK), + TALER_TESTING_cmd_deposit_with_ref ( + "deposit-aggtest-2", + "withdraw-coin-aggtest", + 0, + cred.user43_payto, + "{\"items\":[{\"name\":\"foo bar\",\"value\":1}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:2", + MHD_HTTP_OK, + "deposit-aggtest-1"), CMD_EXEC_AGGREGATOR ("aggregation-aggtest"), - TALER_TESTING_cmd_check_bank_transfer ("check-bank-transfer-aggtest", - cred.exchange_url, - "EUR:3.97", - cred.exchange_payto, - cred.user43_payto), + TALER_TESTING_cmd_check_bank_transfer ( + "check-bank-transfer-aggtest", + cred.exchange_url, + "EUR:3.97", + cred.exchange_payto, + cred.user43_payto), TALER_TESTING_cmd_check_bank_empty ("check-bank-empty-aggtest"), TALER_TESTING_cmd_end () }; @@ -714,35 +749,39 @@ run (void *cls, * Fill reserve with EUR:5.01, as withdraw fee is 1 ct per * config. */ - CMD_TRANSFER_TO_EXCHANGE ("create-reserve-r1", - "EUR:5.01"), - TALER_TESTING_cmd_check_bank_admin_transfer ("check-create-reserve-r1", - "EUR:5.01", - cred.user42_payto, - cred.exchange_payto, - "create-reserve-r1"), + CMD_TRANSFER_TO_EXCHANGE ( + "create-reserve-r1", + "EUR:5.01"), + TALER_TESTING_cmd_check_bank_admin_transfer ( + "check-create-reserve-r1", + "EUR:5.01", + cred.user42_payto, + cred.exchange_payto, + "create-reserve-r1"), /** * Run wire-watch to trigger the reserve creation. */ CMD_EXEC_WIREWATCH ("wirewatch-3"), /* Withdraw a 5 EUR coin, at fee of 1 ct */ - TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-r1", - "create-reserve-r1", - "EUR:5", - 0, /* age restriction off */ - MHD_HTTP_OK), + TALER_TESTING_cmd_withdraw_amount ( + "withdraw-coin-r1", + "create-reserve-r1", + "EUR:5", + 0, /* age restriction off */ + MHD_HTTP_OK), /** * Spend 5 EUR of the 5 EUR coin (in full) (merchant would * receive EUR:4.99 due to 1 ct deposit fee) */ - TALER_TESTING_cmd_deposit ("deposit-refund-1", - "withdraw-coin-r1", - 0, - cred.user42_payto, - "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:5\"}]}", - GNUNET_TIME_UNIT_MINUTES, - "EUR:5", - MHD_HTTP_OK), + TALER_TESTING_cmd_deposit ( + "deposit-refund-1", + "withdraw-coin-r1", + 0, + cred.user42_payto, + "{\"items\":[{\"name\":\"blue ice cream\",\"value\":\"EUR:5\"}]}", + GNUNET_TIME_UNIT_MINUTES, + "EUR:5", + MHD_HTTP_OK), /** * Run transfers. Should do nothing as refund deadline blocks it */ @@ -753,47 +792,53 @@ run (void *cls, * fakebank and the second to actually check there are not * other transfers around. */ TALER_TESTING_cmd_check_bank_empty ("check_bank_transfer-pre-refund"), - TALER_TESTING_cmd_refund_with_id ("refund-ok", - MHD_HTTP_OK, - "EUR:3", - "deposit-refund-1", - 3), - TALER_TESTING_cmd_refund_with_id ("refund-ok-double", - MHD_HTTP_OK, - "EUR:3", - "deposit-refund-1", - 3), + TALER_TESTING_cmd_refund_with_id ( + "refund-ok", + MHD_HTTP_OK, + "EUR:3", + "deposit-refund-1", + 3), + TALER_TESTING_cmd_refund_with_id ( + "refund-ok-double", + MHD_HTTP_OK, + "EUR:3", + "deposit-refund-1", + 3), /* Previous /refund(s) had id == 0. */ - TALER_TESTING_cmd_refund_with_id ("refund-conflicting", - MHD_HTTP_CONFLICT, - "EUR:5", - "deposit-refund-1", - 1), - TALER_TESTING_cmd_deposit ("deposit-refund-insufficient-refund", - "withdraw-coin-r1", - 0, - cred.user42_payto, - "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:4\"}]}", - GNUNET_TIME_UNIT_MINUTES, - "EUR:4", - MHD_HTTP_CONFLICT), - TALER_TESTING_cmd_refund_with_id ("refund-ok-increase", - MHD_HTTP_OK, - "EUR:2", - "deposit-refund-1", - 2), + TALER_TESTING_cmd_refund_with_id ( + "refund-conflicting", + MHD_HTTP_CONFLICT, + "EUR:5", + "deposit-refund-1", + 1), + TALER_TESTING_cmd_deposit ( + "deposit-refund-insufficient-refund", + "withdraw-coin-r1", + 0, + cred.user42_payto, + "{\"items\":[{\"name\":\"fruit ice cream\",\"value\":\"EUR:4\"}]}", + GNUNET_TIME_UNIT_MINUTES, + "EUR:4", + MHD_HTTP_CONFLICT), + TALER_TESTING_cmd_refund_with_id ( + "refund-ok-increase", + MHD_HTTP_OK, + "EUR:2", + "deposit-refund-1", + 2), /** * Spend 4.99 EUR of the refunded 4.99 EUR coin (1ct gone * due to refund) (merchant would receive EUR:4.98 due to * 1 ct deposit fee) */ - TALER_TESTING_cmd_deposit ("deposit-refund-2", - "withdraw-coin-r1", - 0, - cred.user42_payto, - "{\"items\":[{\"name\":\"more ice cream\",\"value\":\"EUR:5\"}]}", - GNUNET_TIME_UNIT_ZERO, - "EUR:4.99", - MHD_HTTP_OK), + TALER_TESTING_cmd_deposit ( + "deposit-refund-2", + "withdraw-coin-r1", + 0, + cred.user42_payto, + "{\"items\":[{\"name\":\"more ice cream\",\"value\":\"EUR:5\"}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:4.99", + MHD_HTTP_OK), /** * Run transfers. This will do the transfer as refund deadline * was 0 @@ -802,52 +847,59 @@ run (void *cls, /** * Check that deposit did run. */ - TALER_TESTING_cmd_check_bank_transfer ("check_bank_transfer-pre-refund", - cred.exchange_url, - "EUR:4.97", - cred.exchange_payto, - cred.user42_payto), + TALER_TESTING_cmd_check_bank_transfer ( + "check_bank_transfer-pre-refund", + cred.exchange_url, + "EUR:4.97", + cred.exchange_payto, + cred.user42_payto), /** * Run failing refund, as past deadline & aggregation. */ - TALER_TESTING_cmd_refund ("refund-fail", - MHD_HTTP_GONE, - "EUR:4.99", - "deposit-refund-2"), + TALER_TESTING_cmd_refund ( + "refund-fail", + MHD_HTTP_GONE, + "EUR:4.99", + "deposit-refund-2"), TALER_TESTING_cmd_check_bank_empty ("check-empty-after-refund"), /** * Test refunded coins are never executed, even past * refund deadline */ - CMD_TRANSFER_TO_EXCHANGE ("create-reserve-rb", - "EUR:5.01"), - TALER_TESTING_cmd_check_bank_admin_transfer ("check-create-reserve-rb", - "EUR:5.01", - cred.user42_payto, - cred.exchange_payto, - "create-reserve-rb"), + CMD_TRANSFER_TO_EXCHANGE ( + "create-reserve-rb", + "EUR:5.01"), + TALER_TESTING_cmd_check_bank_admin_transfer ( + "check-create-reserve-rb", + "EUR:5.01", + cred.user42_payto, + cred.exchange_payto, + "create-reserve-rb"), CMD_EXEC_WIREWATCH ("wirewatch-rb"), - TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-rb", - "create-reserve-rb", - "EUR:5", - 0, /* age restriction off */ - MHD_HTTP_OK), - TALER_TESTING_cmd_deposit ("deposit-refund-1b", - "withdraw-coin-rb", - 0, - cred.user42_payto, - "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:5\"}]}", - GNUNET_TIME_UNIT_ZERO, - "EUR:5", - MHD_HTTP_OK), + TALER_TESTING_cmd_withdraw_amount ( + "withdraw-coin-rb", + "create-reserve-rb", + "EUR:5", + 0, /* age restriction off */ + MHD_HTTP_OK), + TALER_TESTING_cmd_deposit ( + "deposit-refund-1b", + "withdraw-coin-rb", + 0, + cred.user42_payto, + "{\"items\":[{\"name\":\"purple ice cream\",\"value\":\"EUR:5\"}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:5", + MHD_HTTP_OK), /** * Trigger refund (before aggregator had a chance to execute * deposit, even though refund deadline was zero). */ - TALER_TESTING_cmd_refund ("refund-ok-fast", - MHD_HTTP_OK, - "EUR:5", - "deposit-refund-1b"), + TALER_TESTING_cmd_refund ( + "refund-ok-fast", + MHD_HTTP_OK, + "EUR:5", + "deposit-refund-1b"), /** * Run transfers. This will do the transfer as refund deadline * was 0, except of course because the refund succeeded, the @@ -864,8 +916,9 @@ run (void *cls, * Fill reserve with EUR:5.01, as withdraw fee is 1 ct per * config. */ - CMD_TRANSFER_TO_EXCHANGE ("recoup-create-reserve-1", - "EUR:15.02"), + CMD_TRANSFER_TO_EXCHANGE ( + "recoup-create-reserve-1", + "EUR:15.02"), TALER_TESTING_cmd_check_bank_admin_transfer ( "recoup-create-reserve-1-check", "EUR:15.02", @@ -877,156 +930,185 @@ run (void *cls, */ CMD_EXEC_WIREWATCH ("wirewatch-4"), /* Withdraw a 5 EUR coin, at fee of 1 ct */ - TALER_TESTING_cmd_withdraw_amount ("recoup-withdraw-coin-1", - "recoup-create-reserve-1", - "EUR:5", - 0, /* age restriction off */ - MHD_HTTP_OK), + TALER_TESTING_cmd_withdraw_amount ( + "recoup-withdraw-coin-1", + "recoup-create-reserve-1", + "EUR:5", + 0, /* age restriction off */ + MHD_HTTP_OK), /* Withdraw a 10 EUR coin, at fee of 1 ct */ - TALER_TESTING_cmd_withdraw_amount ("recoup-withdraw-coin-1b", - "recoup-create-reserve-1", - "EUR:10", - 0, /* age restriction off */ - MHD_HTTP_OK), + TALER_TESTING_cmd_withdraw_amount ( + "recoup-withdraw-coin-1b", + "recoup-create-reserve-1", + "EUR:10", + 0, /* age restriction off */ + MHD_HTTP_OK), /* melt 10 EUR coin to get 5 EUR refreshed coin */ - TALER_TESTING_cmd_melt ("recoup-melt-coin-1b", - "recoup-withdraw-coin-1b", - MHD_HTTP_OK, - "EUR:5", - NULL), - TALER_TESTING_cmd_refresh_reveal ("recoup-reveal-coin-1b", - "recoup-melt-coin-1b", - MHD_HTTP_OK), + TALER_TESTING_cmd_melt ( + "recoup-melt-coin-1b", + "recoup-withdraw-coin-1b", + MHD_HTTP_OK, + "EUR:5", + NULL), + TALER_TESTING_cmd_refresh_reveal ( + "recoup-reveal-coin-1b", + "recoup-melt-coin-1b", + MHD_HTTP_OK), /* Revoke both 5 EUR coins */ - TALER_TESTING_cmd_revoke ("revoke-0-EUR:5", - MHD_HTTP_OK, - "recoup-withdraw-coin-1", - config_file), + TALER_TESTING_cmd_revoke ( + "revoke-0-EUR:5", + MHD_HTTP_OK, + "recoup-withdraw-coin-1", + config_file), /* Recoup coin to reserve */ - TALER_TESTING_cmd_recoup ("recoup-1", - MHD_HTTP_OK, - "recoup-withdraw-coin-1", - "EUR:5"), + TALER_TESTING_cmd_recoup ( + "recoup-1", + MHD_HTTP_OK, + "recoup-withdraw-coin-1", + "EUR:5"), /* Check the money is back with the reserve */ - TALER_TESTING_cmd_status ("recoup-reserve-status-1", - "recoup-create-reserve-1", - "EUR:5.0", - MHD_HTTP_OK), + TALER_TESTING_cmd_status ( + "recoup-reserve-status-1", + "recoup-create-reserve-1", + "EUR:5.0", + MHD_HTTP_OK), /* Recoup-refresh coin to 10 EUR coin */ - TALER_TESTING_cmd_recoup_refresh ("recoup-1b", - MHD_HTTP_OK, - "recoup-reveal-coin-1b", - "recoup-melt-coin-1b", - "EUR:5"), + TALER_TESTING_cmd_recoup_refresh ( + "recoup-1b", + MHD_HTTP_OK, + "recoup-reveal-coin-1b", + "recoup-melt-coin-1b", + "EUR:5"), /* melt 10 EUR coin *again* to get 1 EUR refreshed coin */ - TALER_TESTING_cmd_melt ("recoup-remelt-coin-1a", - "recoup-withdraw-coin-1b", - MHD_HTTP_OK, - "EUR:1", - NULL), - TALER_TESTING_cmd_refresh_reveal ("recoup-reveal-coin-1a", - "recoup-remelt-coin-1a", - MHD_HTTP_OK), + TALER_TESTING_cmd_melt ( + "recoup-remelt-coin-1a", + "recoup-withdraw-coin-1b", + MHD_HTTP_OK, + "EUR:1", + NULL), + TALER_TESTING_cmd_refresh_reveal ( + "recoup-reveal-coin-1a", + "recoup-remelt-coin-1a", + MHD_HTTP_OK), /* Try melting for more than the residual value to provoke an error */ - TALER_TESTING_cmd_melt ("recoup-remelt-coin-1b", - "recoup-withdraw-coin-1b", - MHD_HTTP_OK, - "EUR:1", - NULL), - TALER_TESTING_cmd_melt ("recoup-remelt-coin-1c", - "recoup-withdraw-coin-1b", - MHD_HTTP_OK, - "EUR:1", - NULL), - TALER_TESTING_cmd_melt ("recoup-remelt-coin-1d", - "recoup-withdraw-coin-1b", - MHD_HTTP_OK, - "EUR:1", - NULL), - TALER_TESTING_cmd_melt ("recoup-remelt-coin-1e", - "recoup-withdraw-coin-1b", - MHD_HTTP_OK, - "EUR:1", - NULL), - TALER_TESTING_cmd_melt ("recoup-remelt-coin-1f", - "recoup-withdraw-coin-1b", - MHD_HTTP_OK, - "EUR:1", - NULL), - TALER_TESTING_cmd_melt ("recoup-remelt-coin-1g", - "recoup-withdraw-coin-1b", - MHD_HTTP_OK, - "EUR:1", - NULL), - TALER_TESTING_cmd_melt ("recoup-remelt-coin-1h", - "recoup-withdraw-coin-1b", - MHD_HTTP_OK, - "EUR:1", - NULL), - TALER_TESTING_cmd_melt ("recoup-remelt-coin-1i", - "recoup-withdraw-coin-1b", - MHD_HTTP_OK, - "EUR:1", - NULL), - TALER_TESTING_cmd_melt ("recoup-remelt-coin-1b-failing", - "recoup-withdraw-coin-1b", - MHD_HTTP_CONFLICT, - "EUR:1", - NULL), + TALER_TESTING_cmd_melt ( + "recoup-remelt-coin-1b", + "recoup-withdraw-coin-1b", + MHD_HTTP_OK, + "EUR:1", + NULL), + TALER_TESTING_cmd_melt ( + "recoup-remelt-coin-1c", + "recoup-withdraw-coin-1b", + MHD_HTTP_OK, + "EUR:1", + NULL), + TALER_TESTING_cmd_melt ( + "recoup-remelt-coin-1d", + "recoup-withdraw-coin-1b", + MHD_HTTP_OK, + "EUR:1", + NULL), + TALER_TESTING_cmd_melt ( + "recoup-remelt-coin-1e", + "recoup-withdraw-coin-1b", + MHD_HTTP_OK, + "EUR:1", + NULL), + TALER_TESTING_cmd_melt ( + "recoup-remelt-coin-1f", + "recoup-withdraw-coin-1b", + MHD_HTTP_OK, + "EUR:1", + NULL), + TALER_TESTING_cmd_melt ( + "recoup-remelt-coin-1g", + "recoup-withdraw-coin-1b", + MHD_HTTP_OK, + "EUR:1", + NULL), + TALER_TESTING_cmd_melt ( + "recoup-remelt-coin-1h", + "recoup-withdraw-coin-1b", + MHD_HTTP_OK, + "EUR:1", + NULL), + TALER_TESTING_cmd_melt ( + "recoup-remelt-coin-1i", + "recoup-withdraw-coin-1b", + MHD_HTTP_OK, + "EUR:1", + NULL), + TALER_TESTING_cmd_melt ( + "recoup-remelt-coin-1b-failing", + "recoup-withdraw-coin-1b", + MHD_HTTP_CONFLICT, + "EUR:1", + NULL), /* Re-withdraw from this reserve */ - TALER_TESTING_cmd_withdraw_amount ("recoup-withdraw-coin-2", - "recoup-create-reserve-1", - "EUR:1", - 0, /* age restriction off */ - MHD_HTTP_OK), + TALER_TESTING_cmd_withdraw_amount ( + "recoup-withdraw-coin-2", + "recoup-create-reserve-1", + "EUR:1", + 0, /* age restriction off */ + MHD_HTTP_OK), /** * This withdrawal will test the logic to create a "recoup" * element to insert into the reserve's history. */ - TALER_TESTING_cmd_withdraw_amount ("recoup-withdraw-coin-2-over", - "recoup-create-reserve-1", - "EUR:10", - 0, /* age restriction off */ - MHD_HTTP_CONFLICT), - TALER_TESTING_cmd_status ("recoup-reserve-status-2", - "recoup-create-reserve-1", - "EUR:3.99", - MHD_HTTP_OK), + TALER_TESTING_cmd_withdraw_amount ( + "recoup-withdraw-coin-2-over", + "recoup-create-reserve-1", + "EUR:10", + 0, /* age restriction off */ + MHD_HTTP_CONFLICT), + TALER_TESTING_cmd_status ( + "recoup-reserve-status-2", + "recoup-create-reserve-1", + "EUR:3.99", + MHD_HTTP_OK), /* These commands should close the reserve because * the aggregator is given a config file that overrides * the reserve expiration time (making it now-ish) */ CMD_TRANSFER_TO_EXCHANGE ("short-lived-reserve", "EUR:5.01"), - TALER_TESTING_cmd_check_bank_admin_transfer ("check-short-lived-reserve", - "EUR:5.01", - cred.user42_payto, - cred.exchange_payto, - "short-lived-reserve"), - TALER_TESTING_cmd_exec_wirewatch2 ("short-lived-aggregation", - config_file_expire_reserve_now, - "exchange-account-2"), - TALER_TESTING_cmd_exec_closer ("close-reserves", - config_file_expire_reserve_now, - "EUR:5", - "EUR:0.01", - "short-lived-reserve"), - TALER_TESTING_cmd_exec_transfer ("close-reserves-transfer", - config_file_expire_reserve_now), + TALER_TESTING_cmd_check_bank_admin_transfer ( + "check-short-lived-reserve", + "EUR:5.01", + cred.user42_payto, + cred.exchange_payto, + "short-lived-reserve"), + TALER_TESTING_cmd_exec_wirewatch2 ( + "short-lived-aggregation", + config_file_expire_reserve_now, + "exchange-account-2"), + TALER_TESTING_cmd_exec_closer ( + "close-reserves", + config_file_expire_reserve_now, + "EUR:5", + "EUR:0.01", + "short-lived-reserve"), + TALER_TESTING_cmd_exec_transfer ( + "close-reserves-transfer", + config_file_expire_reserve_now), - TALER_TESTING_cmd_status ("short-lived-status", - "short-lived-reserve", - "EUR:0", - MHD_HTTP_OK), - TALER_TESTING_cmd_withdraw_amount ("expired-withdraw", - "short-lived-reserve", - "EUR:1", - 0, /* age restriction off */ - MHD_HTTP_CONFLICT), - TALER_TESTING_cmd_check_bank_transfer ("check_bank_short-lived_reimburse", - cred.exchange_url, - "EUR:5", - cred.exchange_payto, - cred.user42_payto), + TALER_TESTING_cmd_status ( + "short-lived-status", + "short-lived-reserve", + "EUR:0", + MHD_HTTP_OK), + TALER_TESTING_cmd_withdraw_amount ( + "expired-withdraw", + "short-lived-reserve", + "EUR:1", + 0, /* age restriction off */ + MHD_HTTP_CONFLICT), + TALER_TESTING_cmd_check_bank_transfer ( + "check_bank_short-lived_reimburse", + cred.exchange_url, + "EUR:5", + cred.exchange_payto, + cred.user42_payto), /* Fill reserve with EUR:2.02, as withdraw fee is 1 ct per * config, then withdraw two coin, partially spend one, and * then have the rest paid back. Check deposit of other coin @@ -1034,76 +1116,87 @@ run (void *cls, * revoked and we did not bother to create a new one... */ CMD_TRANSFER_TO_EXCHANGE ("recoup-create-reserve-2", "EUR:2.02"), - TALER_TESTING_cmd_check_bank_admin_transfer ("ck-recoup-create-reserve-2", - "EUR:2.02", - cred.user42_payto, - cred.exchange_payto, - "recoup-create-reserve-2"), + TALER_TESTING_cmd_check_bank_admin_transfer ( + "ck-recoup-create-reserve-2", + "EUR:2.02", + cred.user42_payto, + cred.exchange_payto, + "recoup-create-reserve-2"), /* Make previous command effective. */ CMD_EXEC_WIREWATCH ("wirewatch-5"), /* Withdraw a 1 EUR coin, at fee of 1 ct */ - TALER_TESTING_cmd_withdraw_amount ("recoup-withdraw-coin-2a", - "recoup-create-reserve-2", - "EUR:1", - 0, /* age restriction off */ - MHD_HTTP_OK), + TALER_TESTING_cmd_withdraw_amount ( + "recoup-withdraw-coin-2a", + "recoup-create-reserve-2", + "EUR:1", + 0, /* age restriction off */ + MHD_HTTP_OK), /* Withdraw a 1 EUR coin, at fee of 1 ct */ - TALER_TESTING_cmd_withdraw_amount ("recoup-withdraw-coin-2b", - "recoup-create-reserve-2", - "EUR:1", - 0, /* age restriction off */ - MHD_HTTP_OK), - TALER_TESTING_cmd_deposit ("recoup-deposit-partial", - "recoup-withdraw-coin-2a", - 0, - cred.user42_payto, - "{\"items\":[{\"name\":\"more ice cream\",\"value\":1}]}", - GNUNET_TIME_UNIT_ZERO, - "EUR:0.5", - MHD_HTTP_OK), - TALER_TESTING_cmd_revoke ("revoke-1-EUR:1", - MHD_HTTP_OK, - "recoup-withdraw-coin-2a", - config_file), + TALER_TESTING_cmd_withdraw_amount ( + "recoup-withdraw-coin-2b", + "recoup-create-reserve-2", + "EUR:1", + 0, /* age restriction off */ + MHD_HTTP_OK), + TALER_TESTING_cmd_deposit ( + "recoup-deposit-partial", + "recoup-withdraw-coin-2a", + 0, + cred.user42_payto, + "{\"items\":[{\"name\":\"more ice cream\",\"value\":1}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:0.5", + MHD_HTTP_OK), + TALER_TESTING_cmd_revoke ( + "revoke-1-EUR:1", + MHD_HTTP_OK, + "recoup-withdraw-coin-2a", + config_file), /* Check recoup is failing for the coin with the reused coin key (fails either because of denomination conflict (RSA) or double-spending (CS))*/ - TALER_TESTING_cmd_recoup ("recoup-2x", - MHD_HTTP_CONFLICT, - "withdraw-coin-1x", - "EUR:1"), - TALER_TESTING_cmd_recoup ("recoup-2", - MHD_HTTP_OK, - "recoup-withdraw-coin-2a", - "EUR:0.5"), + TALER_TESTING_cmd_recoup ( + "recoup-2x", + MHD_HTTP_CONFLICT, + "withdraw-coin-1x", + "EUR:1"), + TALER_TESTING_cmd_recoup ( + "recoup-2", + MHD_HTTP_OK, + "recoup-withdraw-coin-2a", + "EUR:0.5"), /* Idempotency of recoup (withdrawal variant) */ - TALER_TESTING_cmd_recoup ("recoup-2b", - MHD_HTTP_OK, - "recoup-withdraw-coin-2a", - "EUR:0.5"), - TALER_TESTING_cmd_deposit ("recoup-deposit-revoked", - "recoup-withdraw-coin-2b", - 0, - cred.user42_payto, - "{\"items\":[{\"name\":\"more ice cream\",\"value\":1}]}", - GNUNET_TIME_UNIT_ZERO, - "EUR:1", - MHD_HTTP_GONE), + TALER_TESTING_cmd_recoup ( + "recoup-2b", + MHD_HTTP_OK, + "recoup-withdraw-coin-2a", + "EUR:0.5"), + TALER_TESTING_cmd_deposit ( + "recoup-deposit-revoked", + "recoup-withdraw-coin-2b", + 0, + cred.user42_payto, + "{\"items\":[{\"name\":\"gnu ice cream\",\"value\":1}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:1", + MHD_HTTP_GONE), /* Test deposit fails after recoup, with proof in recoup */ /* Note that, the exchange will never return the coin's transaction * history with recoup data, as we get a 410 on the DK! */ - TALER_TESTING_cmd_deposit ("recoup-deposit-partial-after-recoup", - "recoup-withdraw-coin-2a", - 0, - cred.user42_payto, - "{\"items\":[{\"name\":\"extra ice cream\",\"value\":1}]}", - GNUNET_TIME_UNIT_ZERO, - "EUR:0.5", - MHD_HTTP_GONE), + TALER_TESTING_cmd_deposit ( + "recoup-deposit-partial-after-recoup", + "recoup-withdraw-coin-2a", + 0, + cred.user42_payto, + "{\"items\":[{\"name\":\"extra ice cream\",\"value\":1}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:0.5", + MHD_HTTP_GONE), /* Test that revoked coins cannot be withdrawn */ - CMD_TRANSFER_TO_EXCHANGE ("recoup-create-reserve-3", - "EUR:1.01"), + CMD_TRANSFER_TO_EXCHANGE ( + "recoup-create-reserve-3", + "EUR:1.01"), TALER_TESTING_cmd_check_bank_admin_transfer ( "check-recoup-create-reserve-3", "EUR:1.01", @@ -1111,11 +1204,12 @@ run (void *cls, cred.exchange_payto, "recoup-create-reserve-3"), CMD_EXEC_WIREWATCH ("wirewatch-6"), - TALER_TESTING_cmd_withdraw_amount ("recoup-withdraw-coin-3-revoked", - "recoup-create-reserve-3", - "EUR:1", - 0, /* age restriction off */ - MHD_HTTP_GONE), + TALER_TESTING_cmd_withdraw_amount ( + "recoup-withdraw-coin-3-revoked", + "recoup-create-reserve-3", + "EUR:1", + 0, /* age restriction off */ + MHD_HTTP_GONE), /* check that we are empty before the rejection test */ TALER_TESTING_cmd_check_bank_empty ("check-empty-again"), @@ -1129,64 +1223,73 @@ run (void *cls, /** * Move money to the exchange's bank account. */ - CMD_TRANSFER_TO_EXCHANGE ("create-batch-reserve-1", - "EUR:6.03"), - TALER_TESTING_cmd_reserve_poll ("poll-batch-reserve-1", - "create-batch-reserve-1", - "EUR:6.03", - GNUNET_TIME_UNIT_MINUTES, - MHD_HTTP_OK), - TALER_TESTING_cmd_check_bank_admin_transfer ("check-create-batch-reserve-1", - "EUR:6.03", - cred.user42_payto, - cred.exchange_payto, - "create-batch-reserve-1"), + CMD_TRANSFER_TO_EXCHANGE ( + "create-batch-reserve-1", + "EUR:6.03"), + TALER_TESTING_cmd_reserve_poll ( + "poll-batch-reserve-1", + "create-batch-reserve-1", + "EUR:6.03", + GNUNET_TIME_UNIT_MINUTES, + MHD_HTTP_OK), + TALER_TESTING_cmd_check_bank_admin_transfer ( + "check-create-batch-reserve-1", + "EUR:6.03", + cred.user42_payto, + cred.exchange_payto, + "create-batch-reserve-1"), /* * Make a reserve exist, according to the previous * transfer. */ CMD_EXEC_WIREWATCH ("wirewatch-batch-1"), - TALER_TESTING_cmd_reserve_poll_finish ("finish-poll-batch-reserve-1", - GNUNET_TIME_UNIT_SECONDS, - "poll-batch-reserve-1"), + TALER_TESTING_cmd_reserve_poll_finish ( + "finish-poll-batch-reserve-1", + GNUNET_TIME_UNIT_SECONDS, + "poll-batch-reserve-1"), /** * Withdraw EUR:5 AND EUR:1. */ - TALER_TESTING_cmd_batch_withdraw ("batch-withdraw-coin-1", - "create-batch-reserve-1", - 0, /* age restriction off */ - MHD_HTTP_OK, - "EUR:5", - "EUR:1", - NULL), + TALER_TESTING_cmd_batch_withdraw ( + "batch-withdraw-coin-1", + "create-batch-reserve-1", + 0, /* age restriction off */ + MHD_HTTP_OK, + "EUR:5", + "EUR:1", + NULL), /** * Check the reserve is (almost) depleted. */ - TALER_TESTING_cmd_status ("status-batch-1", - "create-batch-reserve-1", - "EUR:0.01", - MHD_HTTP_OK), - TALER_TESTING_cmd_reserve_history ("history-batch-1", - "create-batch-reserve-1", - "EUR:0.01", - MHD_HTTP_OK), + TALER_TESTING_cmd_status ( + "status-batch-1", + "create-batch-reserve-1", + "EUR:0.01", + MHD_HTTP_OK), + TALER_TESTING_cmd_reserve_history ( + "history-batch-1", + "create-batch-reserve-1", + "EUR:0.01", + MHD_HTTP_OK), /** * Spend the coins. */ - TALER_TESTING_cmd_batch_deposit ("batch-deposit-1", - cred.user42_payto, - "{\"items\":[{\"name\":\"ice cream\",\"value\":5}]}", - GNUNET_TIME_UNIT_ZERO, - MHD_HTTP_OK, - "batch-withdraw-coin-1#0", - "EUR:5", - "batch-withdraw-coin-1#1", - "EUR:1", - NULL), - TALER_TESTING_cmd_coin_history ("coin-history-batch-1", - "batch-withdraw-coin-1#0", - "EUR:0.0", - MHD_HTTP_OK), + TALER_TESTING_cmd_batch_deposit ( + "batch-deposit-1", + cred.user42_payto, + "{\"items\":[{\"name\":\"final ice cream\",\"value\":5}]}", + GNUNET_TIME_UNIT_ZERO, + MHD_HTTP_OK, + "batch-withdraw-coin-1#0", + "EUR:5", + "batch-withdraw-coin-1#1", + "EUR:1", + NULL), + TALER_TESTING_cmd_coin_history ( + "coin-history-batch-1", + "batch-withdraw-coin-1#0", + "EUR:0.0", + MHD_HTTP_OK), TALER_TESTING_cmd_end () }; diff --git a/src/testing/test_exchange_api.conf b/src/testing/test_exchange_api.conf index 15fcb72d9..52365ea61 100644 --- a/src/testing/test_exchange_api.conf +++ b/src/testing/test_exchange_api.conf @@ -15,6 +15,7 @@ WIRE_TYPE = iban IBAN_PAYTO_BIC = SANDBOXX SERVE = tcp PORT = 8082 +PWD_HASH_CONFIG = { "cost": 4 } [libeufin-bankdb-postgres] CONFIG = postgresql:///talercheck @@ -85,20 +86,19 @@ ENABLE_CREDIT = YES [exchange-accountcredentials-2] WIRE_GATEWAY_AUTH_METHOD = basic USERNAME = Exchange -PASSWORD = x +PASSWORD = password WIRE_GATEWAY_URL = "http://localhost:8082/accounts/2/taler-wire-gateway/" [admin-accountcredentials-2] WIRE_GATEWAY_AUTH_METHOD = basic # For now, fakebank still checks against the Exchange account... USERNAME = Exchange -PASSWORD = x +PASSWORD = password WIRE_GATEWAY_URL = "http://localhost:8082/accounts/2/taler-wire-gateway/" [kyc-provider-test-oauth2] LOGIC = oauth2 -CONVERTER = taler-exchange-helper-converter-oauth2-address KYC_OAUTH2_VALIDITY = forever KYC_OAUTH2_TOKEN_URL = http://localhost:6666/oauth/v2/token KYC_OAUTH2_AUTHORIZE_URL = http://localhost:6666/oauth/v2/login diff --git a/src/testing/test_exchange_api_age_restriction.c b/src/testing/test_exchange_api_age_restriction.c index 94130132b..75c3a41f8 100644 --- a/src/testing/test_exchange_api_age_restriction.c +++ b/src/testing/test_exchange_api_age_restriction.c @@ -99,7 +99,6 @@ static void run (void *cls, struct TALER_TESTING_Interpreter *is) { - (void) cls; /** * Test withdrawal with age restriction. Success is expected (because the * amount is below the kyc threshold ), so it MUST be @@ -145,12 +144,37 @@ run (void *cls, /** * Spend the coin. */ + TALER_TESTING_cmd_set_var ( + "account-priv", + TALER_TESTING_cmd_deposit ( + "deposit-simple-age-fail-kyc", + "withdraw-coin-age-1", + 0, + cred.user42_payto, + "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:4.99", + MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS)), + TALER_TESTING_cmd_admin_add_kycauth ( + "kyc-auth-transfer", + "EUR:0.01", + &cred.ba, + cred.user42_payto, + "deposit-simple-age-fail-kyc"), + TALER_TESTING_cmd_admin_add_kycauth ( + "kyc-auth-transfer", + "EUR:0.01", + &cred.ba, + cred.user43_payto, + "deposit-simple-age-fail-kyc"), + CMD_EXEC_WIREWATCH ( + "import-kyc-account-withdraw"), TALER_TESTING_cmd_deposit ( "deposit-simple-age", "withdraw-coin-age-1", 0, cred.user42_payto, - "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}", + "{\"items\":[{\"name\":\"ice cream\",\"value\":2}]}", GNUNET_TIME_UNIT_ZERO, "EUR:4.99", MHD_HTTP_OK), @@ -195,7 +219,7 @@ run (void *cls, "refresh-withdraw-coin-age-1", 0, cred.user42_payto, - "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:1\"}]}", + "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:3\"}]}", GNUNET_TIME_UNIT_ZERO, "EUR:1", MHD_HTTP_OK), @@ -237,7 +261,7 @@ run (void *cls, "refresh-reveal-age-1-idempotency", 0, cred.user42_payto, - "{\"items\":[{\"name\":\"ice cream\",\"value\":3}]}", + "{\"items\":[{\"name\":\"ice cream\",\"value\":4}]}", GNUNET_TIME_UNIT_ZERO, "EUR:1", MHD_HTTP_OK), @@ -249,7 +273,7 @@ run (void *cls, "refresh-reveal-age-1", 3, cred.user43_payto, - "{\"items\":[{\"name\":\"ice cream\",\"value\":3}]}", + "{\"items\":[{\"name\":\"ice cream\",\"value\":5}]}", GNUNET_TIME_UNIT_ZERO, "EUR:0.1", MHD_HTTP_OK), @@ -302,6 +326,7 @@ run (void *cls, "check-kyc-withdraw", "withdraw-coin-1-lacking-kyc", "setup-account-key", + TALER_EXCHANGE_KLPT_KYC_AUTH_TRANSFER, MHD_HTTP_ACCEPTED), TALER_TESTING_cmd_get_kyc_info ( "get-kyc-info", @@ -380,6 +405,7 @@ run (void *cls, TALER_TESTING_cmd_end () }; + (void) cls; TALER_TESTING_run (is, commands); } diff --git a/src/testing/test_exchange_api_age_restriction.conf b/src/testing/test_exchange_api_age_restriction.conf index d814519da..b47be9fcc 100644 --- a/src/testing/test_exchange_api_age_restriction.conf +++ b/src/testing/test_exchange_api_age_restriction.conf @@ -66,13 +66,13 @@ ENABLE_CREDIT = YES [exchange-accountcredentials-2] WIRE_GATEWAY_AUTH_METHOD = basic USERNAME = Exchange -PASSWORD = x +PASSWORD = password WIRE_GATEWAY_URL = "http://localhost:8082/accounts/2/taler-wire-gateway/" [admin-accountcredentials-2] WIRE_GATEWAY_AUTH_METHOD = basic USERNAME = Exchange -PASSWORD = x +PASSWORD = password WIRE_GATEWAY_URL = "http://localhost:8082/accounts/2/taler-wire-gateway/" [exchange-extension-age_restriction] @@ -81,7 +81,6 @@ ENABLED = YES [kyc-provider-test-oauth2] LOGIC = oauth2 -CONVERTER = taler-exchange-helper-converter-oauth2-address KYC_OAUTH2_VALIDITY = forever KYC_OAUTH2_TOKEN_URL = http://localhost:6666/oauth/v2/token KYC_OAUTH2_AUTHORIZE_URL = http://localhost:6666/oauth/v2/login diff --git a/src/testing/test_exchange_api_conflicts.c b/src/testing/test_exchange_api_conflicts.c index 070809d9d..cac1a9135 100644 --- a/src/testing/test_exchange_api_conflicts.c +++ b/src/testing/test_exchange_api_conflicts.c @@ -100,7 +100,6 @@ static void run (void *cls, struct TALER_TESTING_Interpreter *is) { - (void) cls; /** * Test withdrawal with conflicting coins. */ @@ -275,6 +274,7 @@ run (void *cls, TALER_TESTING_cmd_end () }; + (void) cls; TALER_TESTING_run (is, commands); } diff --git a/src/testing/test_exchange_api_conflicts.conf b/src/testing/test_exchange_api_conflicts.conf index d04379f05..d8eb6798e 100644 --- a/src/testing/test_exchange_api_conflicts.conf +++ b/src/testing/test_exchange_api_conflicts.conf @@ -66,13 +66,13 @@ ENABLE_CREDIT = YES [exchange-accountcredentials-2] WIRE_GATEWAY_AUTH_METHOD = basic USERNAME = Exchange -PASSWORD = x +PASSWORD = password WIRE_GATEWAY_URL = "http://localhost:8082/accounts/2/taler-wire-gateway/" [admin-accountcredentials-2] WIRE_GATEWAY_AUTH_METHOD = basic USERNAME = Exchange -PASSWORD = x +PASSWORD = password WIRE_GATEWAY_URL = "http://localhost:8082/accounts/2/taler-wire-gateway/" diff --git a/src/testing/test_exchange_api_keys_cherry_picking.conf b/src/testing/test_exchange_api_keys_cherry_picking.conf index 142242424..105b468d0 100644 --- a/src/testing/test_exchange_api_keys_cherry_picking.conf +++ b/src/testing/test_exchange_api_keys_cherry_picking.conf @@ -46,13 +46,13 @@ ENABLE_CREDIT = YES WIRE_GATEWAY_URL = "http://localhost:9082/accounts/2/taler-wire-gateway/" WIRE_GATEWAY_AUTH_METHOD = basic USERNAME = Exchange -PASSWORD = x +PASSWORD = password [admin-accountcredentials-2] WIRE_GATEWAY_URL = "http://localhost:9082/accounts/2/taler-wire-gateway/" WIRE_GATEWAY_AUTH_METHOD = basic USERNAME = Exchange -PASSWORD = x +PASSWORD = password [bank] HTTP_PORT=8082 diff --git a/src/testing/test_exchange_api_revocation.c b/src/testing/test_exchange_api_revocation.c index 92e36a30a..2b707c968 100644 --- a/src/testing/test_exchange_api_revocation.c +++ b/src/testing/test_exchange_api_revocation.c @@ -48,6 +48,21 @@ static struct TALER_TESTING_Credentials cred; /** + * Execute the taler-exchange-wirewatch command with + * our configuration file. + * + * @param label label to use for the command. + */ +static struct TALER_TESTING_Command +CMD_EXEC_WIREWATCH (const char *label) +{ + return TALER_TESTING_cmd_exec_wirewatch2 (label, + config_file, + "exchange-account-2"); +} + + +/** * Main function that will tell the interpreter what commands to * run. * @@ -86,9 +101,7 @@ run (void *cls, /** * Run wire-watch to trigger the reserve creation. */ - TALER_TESTING_cmd_exec_wirewatch2 ("wirewatch-4", - config_file, - "exchange-account-2"), + CMD_EXEC_WIREWATCH ("wirewatch-4"), /* Withdraw a 5 EUR coin, at fee of 1 ct */ TALER_TESTING_cmd_withdraw_amount ("withdraw-revocation-coin-1", "create-reserve-1", @@ -103,23 +116,44 @@ run (void *cls, MHD_HTTP_OK), /* Try to partially spend (deposit) 1 EUR of the 5 EUR coin (in full) * (merchant would receive EUR:0.99 due to 1 ct deposit fee) */// - TALER_TESTING_cmd_deposit ("deposit-partial", - "withdraw-revocation-coin-1", - 0, - cred.user42_payto, - "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:1\"}]}", - GNUNET_TIME_UNIT_ZERO, - "EUR:1", - MHD_HTTP_OK), + TALER_TESTING_cmd_set_var ( + "account-priv", + TALER_TESTING_cmd_deposit ( + "deposit-partial-fail-kyc", + "withdraw-revocation-coin-1", + 0, + cred.user42_payto, + "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:1\"}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:1", + MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS)), + TALER_TESTING_cmd_admin_add_kycauth ( + "kyc-auth-transfer", + "EUR:0.01", + &cred.ba, + cred.user42_payto, + "deposit-partial-fail-kyc"), + CMD_EXEC_WIREWATCH ( + "import-kyc-account-withdraw"), + TALER_TESTING_cmd_deposit ( + "deposit-partial", + "withdraw-revocation-coin-1", + 0, + cred.user42_payto, + "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:2\"}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:1", + MHD_HTTP_OK), /* Deposit another coin in full */ - TALER_TESTING_cmd_deposit ("deposit-full", - "withdraw-revocation-coin-2", - 0, - cred.user42_payto, - "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:5\"}]}", - GNUNET_TIME_UNIT_ZERO, - "EUR:5", - MHD_HTTP_OK), + TALER_TESTING_cmd_deposit ( + "deposit-full", + "withdraw-revocation-coin-2", + 0, + cred.user42_payto, + "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:5\"}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:5", + MHD_HTTP_OK), /** * Melt SOME of the rest of the coin's value * (EUR:3.17 = 3x EUR:1.03 + 7x EUR:0.13) diff --git a/src/testing/test_exchange_api_twisted.c b/src/testing/test_exchange_api_twisted.c index 75ffe1f15..a31e7a4c3 100644 --- a/src/testing/test_exchange_api_twisted.c +++ b/src/testing/test_exchange_api_twisted.c @@ -124,6 +124,25 @@ run (void *cls, "EUR:5", 0, /* age restriction off */ MHD_HTTP_OK), + TALER_TESTING_cmd_set_var ( + "account-priv", + TALER_TESTING_cmd_deposit ( + "refresh-deposit-partial-fail-kyc", + "refresh-withdraw-coin", + 0, + cred.user42_payto, + "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:1\"}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:1", + MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS)), + TALER_TESTING_cmd_admin_add_kycauth ( + "kyc-auth-transfer", + "EUR:0.01", + &cred.ba, + cred.user42_payto, + "refresh-deposit-partial-fail-kyc"), + CMD_EXEC_WIREWATCH ( + "import-kyc-account-withdraw"), TALER_TESTING_cmd_deposit ( "refresh-deposit-partial", "refresh-withdraw-coin", diff --git a/src/testing/test_exchange_p2p.c b/src/testing/test_exchange_p2p.c index 8fae0864e..821f37272 100644 --- a/src/testing/test_exchange_p2p.c +++ b/src/testing/test_exchange_p2p.c @@ -325,14 +325,14 @@ run (void *cls, GNUNET_TIME_UNIT_SECONDS, 1), /* expiration */ "withdraw-coin-1", - "EUR:1.01", + "EUR:1.02", NULL), TALER_TESTING_cmd_purse_poll ( "push-poll-purse-before-expire", MHD_HTTP_GONE, "purse-with-deposit-expire", "EUR:1", - true, + true, /* wait for merge */ GNUNET_TIME_UNIT_MINUTES), /* This should fail, as too much of the coin is already spend / in a purse */ @@ -499,6 +499,7 @@ run (void *cls, "check-kyc-close-pending", "reserve-101-close-kyc", "setup-account-key", + TALER_EXCHANGE_KLPT_KYC_AUTH_TRANSFER, MHD_HTTP_ACCEPTED), TALER_TESTING_cmd_get_kyc_info ( "get-kyc-info", @@ -519,6 +520,7 @@ run (void *cls, "check-kyc-close-ok", "reserve-101-close-kyc", "setup-account-key", + TALER_EXCHANGE_KLPT_KYC_OK, MHD_HTTP_OK), /* Now it should pass */ TALER_TESTING_cmd_reserve_close ( diff --git a/src/testing/test_kyc_api.c b/src/testing/test_kyc_api.c index 01fda98c5..f79da7f0e 100644 --- a/src/testing/test_kyc_api.c +++ b/src/testing/test_kyc_api.c @@ -144,6 +144,7 @@ run (void *cls, "check-kyc-withdraw", "withdraw-coin-1-lacking-kyc", "setup-account-key-withdraw", + TALER_EXCHANGE_KLPT_KYC_AUTH_TRANSFER, MHD_HTTP_ACCEPTED), TALER_TESTING_cmd_get_kyc_info ( "get-kyc-info-withdraw", @@ -186,6 +187,31 @@ run (void *cls, TALER_TESTING_cmd_end () }; struct TALER_TESTING_Command spend[] = { + TALER_TESTING_cmd_set_var ( + "account-priv", + TALER_TESTING_cmd_deposit ( + "deposit-simple-fail-kyc", + "withdraw-coin-1", + 0, + cred.user43_payto, + "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:5", + MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS)), + TALER_TESTING_cmd_admin_add_kycauth ( + "kyc-auth-transfer", + "EUR:0.01", + &cred.ba, + cred.user42_payto, + "deposit-simple-fail-kyc"), + TALER_TESTING_cmd_admin_add_kycauth ( + "kyc-auth-transfer", + "EUR:0.01", + &cred.ba, + cred.user43_payto, + "deposit-simple-fail-kyc"), + CMD_EXEC_WIREWATCH ( + "import-kyc-account"), TALER_TESTING_cmd_deposit ( "deposit-simple", "withdraw-coin-1", @@ -226,6 +252,7 @@ run (void *cls, "check-kyc-deposit", "track-deposit-kyc-ready", "setup-account-key-deposit", + TALER_EXCHANGE_KLPT_KYC_AUTH_TRANSFER, MHD_HTTP_ACCEPTED), TALER_TESTING_cmd_get_kyc_info ( "get-kyc-info-deposit", @@ -256,6 +283,7 @@ run (void *cls, "check-kyc-deposit-again", "track-deposit-kyc-ready", "setup-account-key-deposit", + TALER_EXCHANGE_KLPT_KYC_AUTH_TRANSFER, MHD_HTTP_ACCEPTED), TALER_TESTING_cmd_get_kyc_info ( "get-kyc-info-deposit-again", @@ -295,6 +323,7 @@ run (void *cls, "check-kyc-wallet", "wallet-kyc-fail", "wallet-kyc-fail", + TALER_EXCHANGE_KLPT_KYC_AUTH_TRANSFER, MHD_HTTP_ACCEPTED), TALER_TESTING_cmd_get_kyc_info ( "get-kyc-info-kyc-wallet", @@ -315,6 +344,7 @@ run (void *cls, "wallet-kyc-check", "wallet-kyc-fail", "wallet-kyc-fail", + TALER_EXCHANGE_KLPT_KYC_AUTH_TRANSFER, MHD_HTTP_OK), TALER_TESTING_cmd_reserve_get_attestable ( "wallet-get-attestable", @@ -429,6 +459,7 @@ run (void *cls, "check-kyc-purse-merge", "purse-merge-into-reserve", "p2p_create-reserve-1", + TALER_EXCHANGE_KLPT_KYC_AUTH_TRANSFER, MHD_HTTP_ACCEPTED), TALER_TESTING_cmd_get_kyc_info ( "get-kyc-info-purse-merge-into-reserve", @@ -482,6 +513,7 @@ run (void *cls, "check-kyc-purse-create", "purse-create-with-reserve", "purse-create-with-reserve", + TALER_EXCHANGE_KLPT_KYC_AUTH_TRANSFER, MHD_HTTP_ACCEPTED), TALER_TESTING_cmd_get_kyc_info ( "get-kyc-info-purse-create", @@ -560,7 +592,7 @@ run (void *cls, "check-decisions-none-normal", "create-aml-officer-1", NULL, - MHD_HTTP_NO_CONTENT), + MHD_HTTP_OK), /* Trigger something upon which an AML officer could act */ TALER_TESTING_cmd_wallet_kyc_get ( "wallet-trigger-kyc-for-aml", @@ -704,7 +736,7 @@ run (void *cls, " ,\"verboten\":false" " }" " ]" /* end new rules */ - ",\"new_measure\":\"form-measure\"" + ",\"new_measures\":\"form-measure\"" ",\"custom_measures\":" " {" " \"form-measure\":" @@ -722,6 +754,7 @@ run (void *cls, "check-kyc-form", "wallet-trigger-kyc-for-form-aml", "wallet-trigger-kyc-for-form-aml", + TALER_EXCHANGE_KLPT_KYC_AUTH_TRANSFER, MHD_HTTP_ACCEPTED), TALER_TESTING_cmd_get_kyc_info ( "get-kyc-info-form", diff --git a/src/testing/testing_api_cmd_age_withdraw.c b/src/testing/testing_api_cmd_age_withdraw.c index ed08773c7..3192fc9b1 100644 --- a/src/testing/testing_api_cmd_age_withdraw.c +++ b/src/testing/testing_api_cmd_age_withdraw.c @@ -742,16 +742,17 @@ TALER_TESTING_cmd_age_withdraw_reveal ( awrs->age_withdraw_reference = age_withdraw_reference; awrs->expected_response_code = expected_response_code; + { + struct TALER_TESTING_Command cmd = { + .cls = awrs, + .label = label, + .run = age_withdraw_reveal_run, + .cleanup = age_withdraw_reveal_cleanup, + .traits = age_withdraw_reveal_traits, + }; - struct TALER_TESTING_Command cmd = { - .cls = awrs, - .label = label, - .run = age_withdraw_reveal_run, - .cleanup = age_withdraw_reveal_cleanup, - .traits = age_withdraw_reveal_traits, - }; - - return cmd; + return cmd; + } } diff --git a/src/testing/testing_api_cmd_batch.c b/src/testing/testing_api_cmd_batch.c index 5bb7b974e..395d92563 100644 --- a/src/testing/testing_api_cmd_batch.c +++ b/src/testing/testing_api_cmd_batch.c @@ -62,27 +62,30 @@ batch_run (void *cls, struct TALER_TESTING_Interpreter *is) { struct BatchState *bs = cls; + struct TALER_TESTING_Command *bcmd = &bs->batch[bs->batch_ip]; bs->cmd = cmd; - if (NULL != bs->batch[bs->batch_ip].label) + if (NULL != bcmd->label) TALER_LOG_INFO ("Running batched command: %s\n", - bs->batch[bs->batch_ip].label); + bcmd->label); /* hit end command, leap to next top-level command. */ - if (NULL == bs->batch[bs->batch_ip].label) + if (NULL == bcmd->label) { TALER_LOG_INFO ("Exiting from batch: %s\n", cmd->label); TALER_TESTING_interpreter_next (is); return; } - bs->batch[bs->batch_ip].start_time - = bs->batch[bs->batch_ip].last_req_time + bcmd->start_time + = bcmd->last_req_time = GNUNET_TIME_absolute_get (); - bs->batch[bs->batch_ip].num_tries = 1; - bs->batch[bs->batch_ip].run (bs->batch[bs->batch_ip].cls, - &bs->batch[bs->batch_ip], - is); + bcmd->num_tries++; + TALER_TESTING_update_variables_ (is, + bcmd); + bcmd->run (bcmd->cls, + bcmd, + is); } diff --git a/src/testing/testing_api_cmd_batch_deposit.c b/src/testing/testing_api_cmd_batch_deposit.c index 5139d3524..199404e1c 100644 --- a/src/testing/testing_api_cmd_batch_deposit.c +++ b/src/testing/testing_api_cmd_batch_deposit.c @@ -39,7 +39,7 @@ * How long do we wait AT MOST when retrying? */ #define MAX_BACKOFF GNUNET_TIME_relative_multiply ( \ - GNUNET_TIME_UNIT_MILLISECONDS, 100) + GNUNET_TIME_UNIT_MILLISECONDS, 100) /** @@ -133,7 +133,13 @@ struct BatchDepositState * Set (by the interpreter) to a fresh private key. This * key will be used to sign the deposit request. */ - struct TALER_MerchantPrivateKeyP merchant_priv; + union TALER_AccountPrivateKeyP account_priv; + + /** + * Set (by the interpreter) to the public key + * corresponding to @e account_priv. + */ + union TALER_AccountPublicKeyP account_pub; /** * Deposit handle while operation is running. @@ -172,6 +178,18 @@ struct BatchDepositState struct TALER_ExchangeSignatureP exchange_sig; /** + * Set to the KYC requirement payto hash *if* the exchange replied with a + * request for KYC. + */ + struct TALER_PaytoHashP h_payto; + + /** + * Set to the KYC requirement row *if* the exchange replied with + * a request for KYC. + */ + uint64_t requirement_row; + + /** * Reference to previous deposit operation. * Only present if we're supposed to replay the previous deposit. */ @@ -218,12 +236,21 @@ batch_deposit_cb (void *cls, ds->expected_response_code); return; } - if (MHD_HTTP_OK == dr->hr.http_status) + switch (dr->hr.http_status) { + case MHD_HTTP_OK: ds->deposit_succeeded = GNUNET_YES; ds->exchange_timestamp = dr->details.ok.deposit_timestamp; ds->exchange_pub = *dr->details.ok.exchange_pub; ds->exchange_sig = *dr->details.ok.exchange_sig; + break; + case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS: + /* nothing to check */ + ds->requirement_row + = dr->details.unavailable_for_legal_reasons.requirement_row; + ds->h_payto + = dr->details.unavailable_for_legal_reasons.h_payto; + break; } TALER_TESTING_interpreter_next (ds->is); } @@ -243,7 +270,6 @@ batch_deposit_run (void *cls, { struct BatchDepositState *ds = cls; const struct TALER_DenominationSignature *denom_pub_sig; - struct TALER_MerchantPublicKeyP merchant_pub; struct TALER_PrivateContractHashP h_contract_terms; enum TALER_ErrorCode ec; struct TALER_WireSaltP wire_salt; @@ -283,6 +309,13 @@ batch_deposit_run (void *cls, TALER_TESTING_interpreter_fail (is); return; } +#if DUMP_CONTRACT + fprintf (stderr, + "Using contract:\n"); + json_dumpf (ds->contract_terms, + stderr, + JSON_INDENT (2)); +#endif if (GNUNET_OK != TALER_JSON_contract_hash (ds->contract_terms, &h_contract_terms)) @@ -311,9 +344,38 @@ batch_deposit_run (void *cls, ds->refund_deadline = ds->wallet_timestamp; ds->wire_deadline = GNUNET_TIME_timestamp_get (); } - GNUNET_CRYPTO_eddsa_key_get_public (&ds->merchant_priv.eddsa_priv, - &merchant_pub.eddsa_pub); + { + const struct TALER_TESTING_Command *acc_var; + if (NULL != (acc_var + = TALER_TESTING_interpreter_get_command ( + is, + "account-priv"))) + { + const union TALER_AccountPrivateKeyP *account_priv; + + if ( (GNUNET_OK != + TALER_TESTING_get_trait_account_priv (acc_var, + &account_priv)) ) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (is); + return; + } + ds->account_priv = *account_priv; + GNUNET_CRYPTO_eddsa_key_get_public ( + &ds->account_priv.merchant_priv.eddsa_priv, + &ds->account_pub.merchant_pub.eddsa_pub); + } + else + { + GNUNET_CRYPTO_eddsa_key_create ( + &ds->account_priv.merchant_priv.eddsa_priv); + GNUNET_CRYPTO_eddsa_key_get_public ( + &ds->account_priv.merchant_priv.eddsa_priv, + &ds->account_pub.merchant_pub.eddsa_pub); + } + } for (unsigned int i = 0; i<ds->num_coins; i++) { struct Coin *coin = &ds->coins[i]; @@ -374,7 +436,7 @@ batch_deposit_run (void *cls, NULL, /* hash of extensions */ &coin->denom_pub->h_key, ds->wallet_timestamp, - &merchant_pub, + &ds->account_pub.merchant_pub, ds->refund_deadline, coin_priv, &cdd->coin_sig); @@ -386,7 +448,7 @@ batch_deposit_run (void *cls, coin->che.details.deposit.no_h_policy = true; coin->che.details.deposit.no_wallet_data_hash = true; coin->che.details.deposit.wallet_timestamp = ds->wallet_timestamp; - coin->che.details.deposit.merchant_pub = merchant_pub; + coin->che.details.deposit.merchant_pub = ds->account_pub.merchant_pub; coin->che.details.deposit.refund_deadline = ds->refund_deadline; coin->che.details.deposit.sig = cdd->coin_sig; coin->che.details.deposit.no_hac = GNUNET_is_zero (&cdd->h_age_commitment); @@ -403,7 +465,7 @@ batch_deposit_run (void *cls, .h_contract_terms = h_contract_terms, .policy_details = NULL /* FIXME #7270-OEC */, .wallet_timestamp = ds->wallet_timestamp, - .merchant_pub = merchant_pub, + .merchant_pub = ds->account_pub.merchant_pub, .refund_deadline = ds->refund_deadline }; @@ -525,7 +587,10 @@ batch_deposit_traits (void *cls, /* These traits are always available */ TALER_TESTING_make_trait_wire_details (ds->wire_details), TALER_TESTING_make_trait_contract_terms (ds->contract_terms), - TALER_TESTING_make_trait_merchant_priv (&ds->merchant_priv), + TALER_TESTING_make_trait_merchant_priv (&ds->account_priv.merchant_priv), + TALER_TESTING_make_trait_merchant_pub (&ds->account_pub.merchant_pub), + TALER_TESTING_make_trait_account_priv (&ds->account_priv), + TALER_TESTING_make_trait_account_pub (&ds->account_pub), TALER_TESTING_make_trait_age_commitment_proof (index, age_commitment_proof), TALER_TESTING_make_trait_coin_history (index, @@ -548,6 +613,8 @@ batch_deposit_traits (void *cls, &ds->wire_deadline), TALER_TESTING_make_trait_refund_deadline (index, &ds->refund_deadline), + TALER_TESTING_make_trait_legi_requirement_row (&ds->requirement_row), + TALER_TESTING_make_trait_h_payto (&ds->h_payto), TALER_TESTING_trait_end () }; @@ -562,12 +629,13 @@ batch_deposit_traits (void *cls, struct TALER_TESTING_Command -TALER_TESTING_cmd_batch_deposit (const char *label, - const char *target_account_payto, - const char *contract_terms, - struct GNUNET_TIME_Relative refund_deadline, - unsigned int expected_response_code, - ...) +TALER_TESTING_cmd_batch_deposit ( + const char *label, + const char *target_account_payto, + const char *contract_terms, + struct GNUNET_TIME_Relative refund_deadline, + unsigned int expected_response_code, + ...) { struct BatchDepositState *ds; va_list ap; @@ -614,7 +682,6 @@ TALER_TESTING_cmd_batch_deposit (const char *label, ds->contract_terms = json_loads (contract_terms, JSON_REJECT_DUPLICATES, NULL); - GNUNET_CRYPTO_eddsa_key_create (&ds->merchant_priv.eddsa_priv); if (NULL == ds->contract_terms) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, diff --git a/src/testing/testing_api_cmd_check_aml_decisions.c b/src/testing/testing_api_cmd_check_aml_decisions.c index 74ad5f66f..0c31c5471 100644 --- a/src/testing/testing_api_cmd_check_aml_decisions.c +++ b/src/testing/testing_api_cmd_check_aml_decisions.c @@ -155,7 +155,7 @@ check_aml_decisions_run ( struct TALER_TESTING_Interpreter *is) { struct AmlCheckState *ds = cls; - const struct TALER_PaytoHashP *h_payto; + const struct TALER_PaytoHashP *h_payto = NULL; const struct TALER_AmlOfficerPrivateKeyP *officer_priv; const struct TALER_TESTING_Command *ref; const char *exchange_url; diff --git a/src/testing/testing_api_cmd_deposit.c b/src/testing/testing_api_cmd_deposit.c index 849c78c70..f45fce133 100644 --- a/src/testing/testing_api_cmd_deposit.c +++ b/src/testing/testing_api_cmd_deposit.c @@ -38,7 +38,7 @@ * How long do we wait AT MOST when retrying? */ #define MAX_BACKOFF GNUNET_TIME_relative_multiply ( \ - GNUNET_TIME_UNIT_MILLISECONDS, 100) + GNUNET_TIME_UNIT_MILLISECONDS, 100) /** @@ -98,7 +98,13 @@ struct DepositState * Set (by the interpreter) to a fresh private key. This * key will be used to sign the deposit request. */ - struct TALER_MerchantPrivateKeyP merchant_priv; + union TALER_AccountPrivateKeyP account_priv; + + /** + * Set (by the interpreter) to the public key + * corresponding to @e account_priv. + */ + union TALER_AccountPublicKeyP account_pub; /** * Deposit handle while operation is running. @@ -297,11 +303,11 @@ deposit_run (void *cls, { struct DepositState *ds = cls; const struct TALER_TESTING_Command *coin_cmd; + const struct TALER_TESTING_Command *acc_var; const struct TALER_CoinSpendPrivateKeyP *coin_priv; struct TALER_CoinSpendPublicKeyP coin_pub; const struct TALER_AgeCommitmentHash *phac; const struct TALER_DenominationSignature *denom_pub_sig; - struct TALER_MerchantPublicKeyP merchant_pub; struct TALER_PrivateContractHashP h_contract_terms; enum TALER_ErrorCode ec; struct TALER_WireSaltP wire_salt; @@ -342,18 +348,18 @@ deposit_run (void *cls, if (NULL != ds->deposit_reference) { /* We're copying another deposit operation, initialize here. */ - const struct TALER_TESTING_Command *cmd; + const struct TALER_TESTING_Command *drcmd; struct DepositState *ods; - cmd = TALER_TESTING_interpreter_lookup_command (is, - ds->deposit_reference); - if (NULL == cmd) + drcmd = TALER_TESTING_interpreter_lookup_command (is, + ds->deposit_reference); + if (NULL == drcmd) { GNUNET_break (0); TALER_TESTING_interpreter_fail (is); return; } - ods = cmd->cls; + ods = drcmd->cls; ds->coin_reference = ods->coin_reference; ds->coin_index = ods->coin_index; ds->wire_details = json_incref (ods->wire_details); @@ -363,32 +369,65 @@ deposit_run (void *cls, ds->refund_deadline = ods->refund_deadline; ds->wire_deadline = ods->wire_deadline; ds->amount = ods->amount; - ds->merchant_priv = ods->merchant_priv; + ds->account_priv = ods->account_priv; + ds->account_pub = ods->account_pub; ds->command_initialized = true; } else if (NULL != ds->merchant_priv_reference) { /* We're copying the merchant key from another deposit operation */ const struct TALER_MerchantPrivateKeyP *merchant_priv; - const struct TALER_TESTING_Command *cmd; + const struct TALER_TESTING_Command *mpcmd; - cmd = TALER_TESTING_interpreter_lookup_command (is, - ds->merchant_priv_reference); - if (NULL == cmd) + mpcmd = TALER_TESTING_interpreter_lookup_command ( + is, + ds->merchant_priv_reference); + if (NULL == mpcmd) { GNUNET_break (0); TALER_TESTING_interpreter_fail (is); return; } if ( (GNUNET_OK != - TALER_TESTING_get_trait_merchant_priv (cmd, + TALER_TESTING_get_trait_merchant_priv (mpcmd, &merchant_priv)) ) { GNUNET_break (0); TALER_TESTING_interpreter_fail (is); return; } - ds->merchant_priv = *merchant_priv; + ds->account_priv.merchant_priv = *merchant_priv; + GNUNET_CRYPTO_eddsa_key_get_public ( + &ds->account_priv.merchant_priv.eddsa_priv, + &ds->account_pub.merchant_pub.eddsa_pub); + } + else if (NULL != (acc_var + = TALER_TESTING_interpreter_get_command ( + is, + "account-priv"))) + { + const union TALER_AccountPrivateKeyP *account_priv; + + if ( (GNUNET_OK != + TALER_TESTING_get_trait_account_priv (acc_var, + &account_priv)) ) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (is); + return; + } + ds->account_priv = *account_priv; + GNUNET_CRYPTO_eddsa_key_get_public ( + &ds->account_priv.merchant_priv.eddsa_priv, + &ds->account_pub.merchant_pub.eddsa_pub); + } + else + { + GNUNET_CRYPTO_eddsa_key_create ( + &ds->account_priv.merchant_priv.eddsa_priv); + GNUNET_CRYPTO_eddsa_key_get_public ( + &ds->account_priv.merchant_priv.eddsa_priv, + &ds->account_pub.merchant_pub.eddsa_pub); } GNUNET_assert (NULL != ds->wire_details); if (GNUNET_OK != @@ -412,7 +451,13 @@ deposit_run (void *cls, TALER_TESTING_interpreter_fail (is); return; } - +#if DUMP_CONTRACT + fprintf (stderr, + "Using contract:\n"); + json_dumpf (ds->contract_terms, + stderr, + JSON_INDENT (2)); +#endif if ( (GNUNET_OK != TALER_TESTING_get_trait_coin_priv (coin_cmd, ds->coin_index, @@ -442,8 +487,6 @@ deposit_run (void *cls, GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv, &coin_pub.eddsa_pub); - GNUNET_CRYPTO_eddsa_key_get_public (&ds->merchant_priv.eddsa_priv, - &merchant_pub.eddsa_pub); { struct TALER_MerchantWireHashP h_wire; @@ -459,7 +502,7 @@ deposit_run (void *cls, NULL, /* hash of extensions */ &ds->denom_pub->h_key, ds->wallet_timestamp, - &merchant_pub, + &ds->account_pub.merchant_pub, ds->refund_deadline, coin_priv, &ds->coin_sig); @@ -470,7 +513,7 @@ deposit_run (void *cls, ds->che.details.deposit.no_h_policy = true; ds->che.details.deposit.no_wallet_data_hash = true; ds->che.details.deposit.wallet_timestamp = ds->wallet_timestamp; - ds->che.details.deposit.merchant_pub = merchant_pub; + ds->che.details.deposit.merchant_pub = ds->account_pub.merchant_pub; ds->che.details.deposit.refund_deadline = ds->refund_deadline; ds->che.details.deposit.sig = ds->coin_sig; ds->che.details.deposit.no_hac = true; @@ -492,7 +535,7 @@ deposit_run (void *cls, .wire_salt = wire_salt, .h_contract_terms = h_contract_terms, .wallet_timestamp = ds->wallet_timestamp, - .merchant_pub = merchant_pub, + .merchant_pub = ds->account_pub.merchant_pub, .refund_deadline = ds->refund_deadline }; @@ -638,7 +681,10 @@ deposit_traits (void *cls, h_age_commitment), TALER_TESTING_make_trait_wire_details (ds->wire_details), TALER_TESTING_make_trait_contract_terms (ds->contract_terms), - TALER_TESTING_make_trait_merchant_priv (&ds->merchant_priv), + TALER_TESTING_make_trait_merchant_priv (&ds->account_priv.merchant_priv), + TALER_TESTING_make_trait_merchant_pub (&ds->account_pub.merchant_pub), + TALER_TESTING_make_trait_account_priv (&ds->account_priv), + TALER_TESTING_make_trait_account_pub (&ds->account_pub), TALER_TESTING_make_trait_deposit_amount (0, &ds->amount), TALER_TESTING_make_trait_deposit_fee_amount (0, @@ -683,7 +729,6 @@ TALER_TESTING_cmd_deposit ( ds->contract_terms = json_loads (contract_terms, JSON_REJECT_DUPLICATES, NULL); - GNUNET_CRYPTO_eddsa_key_create (&ds->merchant_priv.eddsa_priv); if (NULL == ds->contract_terms) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, diff --git a/src/testing/testing_api_cmd_kyc_check_get.c b/src/testing/testing_api_cmd_kyc_check_get.c index 981570153..fa0556d47 100644 --- a/src/testing/testing_api_cmd_kyc_check_get.c +++ b/src/testing/testing_api_cmd_kyc_check_get.c @@ -34,6 +34,22 @@ struct KycCheckGetState { /** + * Set to the KYC URL *if* the exchange replied with + * a request for KYC (#MHD_HTTP_ACCEPTED or #MHD_HTTP_OK). + */ + struct TALER_AccountAccessTokenP access_token; + + /** + * Handle to the "track transaction" pending operation. + */ + struct TALER_EXCHANGE_KycCheckHandle *kwh; + + /** + * Interpreter state. + */ + struct TALER_TESTING_Interpreter *is; + + /** * Command to get a reserve private key from. */ const char *payment_target_reference; @@ -49,20 +65,10 @@ struct KycCheckGetState unsigned int expected_response_code; /** - * Set to the KYC URL *if* the exchange replied with - * a request for KYC (#MHD_HTTP_ACCEPTED or #MHD_HTTP_OK). - */ - struct TALER_AccountAccessTokenP access_token; - - /** - * Handle to the "track transaction" pending operation. + * What are we waiting for when long-polling? */ - struct TALER_EXCHANGE_KycCheckHandle *kwh; + enum TALER_EXCHANGE_KycLongPollTarget lpt; - /** - * Interpreter state. - */ - struct TALER_TESTING_Interpreter *is; }; @@ -120,7 +126,7 @@ check_kyc_run (void *cls, struct KycCheckGetState *kcg = cls; const struct TALER_TESTING_Command *res_cmd; const struct TALER_TESTING_Command *acc_cmd; - const uint64_t *requirement_row; + const struct TALER_PaytoHashP *h_payto; const union TALER_AccountPrivateKeyP *account_priv; (void) cmd; @@ -144,9 +150,9 @@ check_kyc_run (void *cls, return; } if (GNUNET_OK != - TALER_TESTING_get_trait_legi_requirement_row ( + TALER_TESTING_get_trait_h_payto ( res_cmd, - &requirement_row)) + &h_payto)) { GNUNET_break (0); TALER_TESTING_interpreter_fail (kcg->is); @@ -160,7 +166,7 @@ check_kyc_run (void *cls, TALER_TESTING_interpreter_fail (kcg->is); return; } - if (0 == *requirement_row) + if (0 == h_payto) { GNUNET_break (0); TALER_TESTING_interpreter_fail (kcg->is); @@ -169,9 +175,12 @@ check_kyc_run (void *cls, kcg->kwh = TALER_EXCHANGE_kyc_check ( TALER_TESTING_interpreter_get_context (is), TALER_TESTING_get_exchange_url (is), - *requirement_row, + h_payto, account_priv, - GNUNET_TIME_UNIT_ZERO, + kcg->lpt, + TALER_EXCHANGE_KLPT_NONE == kcg->lpt + ? GNUNET_TIME_UNIT_ZERO + : GNUNET_TIME_UNIT_MINUTES, &check_kyc_cb, kcg); GNUNET_assert (NULL != kcg->kwh); @@ -235,6 +244,7 @@ TALER_TESTING_cmd_check_kyc_get ( const char *label, const char *payment_target_reference, const char *account_reference, + enum TALER_EXCHANGE_KycLongPollTarget lpt, unsigned int expected_response_code) { struct KycCheckGetState *kcg; @@ -243,6 +253,7 @@ TALER_TESTING_cmd_check_kyc_get ( kcg->payment_target_reference = payment_target_reference; kcg->account_reference = account_reference; kcg->expected_response_code = expected_response_code; + kcg->lpt = lpt; { struct TALER_TESTING_Command cmd = { .cls = kcg, diff --git a/src/testing/testing_api_cmd_kyc_proof.c b/src/testing/testing_api_cmd_kyc_proof.c index e5135e0f4..af6d9c139 100644 --- a/src/testing/testing_api_cmd_kyc_proof.c +++ b/src/testing/testing_api_cmd_kyc_proof.c @@ -175,7 +175,7 @@ proof_kyc_run (void *cls, /** - * Cleanup the state from a "track transaction" CMD, and possibly + * Cleanup the state from a "kyc proof" CMD, and possibly * cancel a operation thereof. * * @param cls closure. diff --git a/src/testing/testing_api_cmd_kyc_wallet_get.c b/src/testing/testing_api_cmd_kyc_wallet_get.c index 48b5211e7..24bd7d4d7 100644 --- a/src/testing/testing_api_cmd_kyc_wallet_get.c +++ b/src/testing/testing_api_cmd_kyc_wallet_get.c @@ -65,13 +65,13 @@ struct KycWalletGetState /** * Set to the KYC requirement payto hash *if* the exchange replied with a - * request for KYC (#MHD_HTTP_OK). + * request for KYC (#MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS). */ struct TALER_PaytoHashP h_payto; /** * Set to the KYC requirement row *if* the exchange replied with - * a request for KYC (#MHD_HTTP_OK). + * request for KYC (#MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS). */ uint64_t requirement_row; diff --git a/src/testing/testing_api_cmd_purse_get.c b/src/testing/testing_api_cmd_purse_get.c index d5246660b..762c39fa6 100644 --- a/src/testing/testing_api_cmd_purse_get.c +++ b/src/testing/testing_api_cmd_purse_get.c @@ -128,15 +128,9 @@ purse_status_cb (void *cls, ss->pgh = NULL; if (ss->expected_response_code != rs->hr.http_status) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected HTTP response code: %d in %s:%u\n", - rs->hr.http_status, - __FILE__, - __LINE__); - json_dumpf (rs->hr.reply, - stderr, - 0); - TALER_TESTING_interpreter_fail (ss->is); + TALER_TESTING_unexpected_status (is, + rs->hr.http_status, + ss->expected_response_code); return; } if (MHD_HTTP_OK == ss->expected_response_code) diff --git a/src/testing/testing_api_cmd_purse_merge.c b/src/testing/testing_api_cmd_purse_merge.c index cf9d4f996..515a14403 100644 --- a/src/testing/testing_api_cmd_purse_merge.c +++ b/src/testing/testing_api_cmd_purse_merge.c @@ -171,6 +171,10 @@ merge_cb (void *cls, /* KYC required */ ds->requirement_row = dr->details.unavailable_for_legal_reasons.requirement_row; + GNUNET_break (0 == + GNUNET_memcmp ( + &ds->h_payto, + &dr->details.unavailable_for_legal_reasons.h_payto)); break; } diff --git a/src/testing/testing_api_cmd_refresh.c b/src/testing/testing_api_cmd_refresh.c index 111e9118f..5c45e3a33 100644 --- a/src/testing/testing_api_cmd_refresh.c +++ b/src/testing/testing_api_cmd_refresh.c @@ -32,7 +32,7 @@ * How long do we wait AT MOST when retrying? */ #define MAX_BACKOFF GNUNET_TIME_relative_multiply ( \ - GNUNET_TIME_UNIT_MILLISECONDS, 100) + GNUNET_TIME_UNIT_MILLISECONDS, 100) /** * How often do we retry before giving up? @@ -43,7 +43,7 @@ * How long do we wait AT MOST when retrying? */ #define MAX_BACKOFF GNUNET_TIME_relative_multiply ( \ - GNUNET_TIME_UNIT_MILLISECONDS, 100) + GNUNET_TIME_UNIT_MILLISECONDS, 100) /** * Information about a fresh coin generated by the refresh @@ -800,6 +800,7 @@ refresh_link_run (void *cls, const struct TALER_TESTING_Command *melt_cmd; const struct TALER_TESTING_Command *coin_cmd; const char *exchange_url; + const struct TALER_CoinSpendPrivateKeyP *coin_priv; rls->cmd = cmd; rls->is = is; @@ -839,7 +840,6 @@ refresh_link_run (void *cls, return; } - const struct TALER_CoinSpendPrivateKeyP *coin_priv; if (GNUNET_OK != TALER_TESTING_get_trait_coin_priv (coin_cmd, 0, @@ -1021,12 +1021,12 @@ melt_run (void *cls, const struct TALER_TESTING_Command *cmd, struct TALER_TESTING_Interpreter *is) { - struct RefreshMeltState *rms = cls; - unsigned int num_fresh_coins; - const char *default_melt_fresh_amounts[] = { + static const char *default_melt_fresh_amounts[] = { "EUR:1", "EUR:1", "EUR:1", "EUR:0.1", NULL }; + struct RefreshMeltState *rms = cls; + unsigned int num_fresh_coins; const char **melt_fresh_amounts; rms->cmd = cmd; diff --git a/src/testing/testing_api_cmd_reserve_purse.c b/src/testing/testing_api_cmd_reserve_purse.c index 923542082..a083711f6 100644 --- a/src/testing/testing_api_cmd_reserve_purse.c +++ b/src/testing/testing_api_cmd_reserve_purse.c @@ -164,6 +164,10 @@ purse_cb (void *cls, /* KYC required */ ds->requirement_row = dr->details.unavailable_for_legal_reasons.requirement_row; + GNUNET_break (0 == + GNUNET_memcmp ( + &ds->h_payto, + &dr->details.unavailable_for_legal_reasons.h_payto)); break; } TALER_TESTING_interpreter_next (ds->is); diff --git a/src/testing/testing_api_cmd_signal.c b/src/testing/testing_api_cmd_signal.c index be3a58bdd..578c95cb2 100644 --- a/src/testing/testing_api_cmd_signal.c +++ b/src/testing/testing_api_cmd_signal.c @@ -102,13 +102,14 @@ TALER_TESTING_cmd_signal (const char *label, ss->process = process; ss->signal = signal; - - struct TALER_TESTING_Command cmd = { - .cls = ss, - .label = label, - .run = &signal_run, - .cleanup = &signal_cleanup - }; - - return cmd; + { + struct TALER_TESTING_Command cmd = { + .cls = ss, + .label = label, + .run = &signal_run, + .cleanup = &signal_cleanup + }; + + return cmd; + } } diff --git a/src/testing/testing_api_cmd_take_aml_decision.c b/src/testing/testing_api_cmd_take_aml_decision.c index e61c03efa..bfe741869 100644 --- a/src/testing/testing_api_cmd_take_aml_decision.c +++ b/src/testing/testing_api_cmd_take_aml_decision.c @@ -149,7 +149,7 @@ take_aml_decision_run (void *cls, const json_t *jmeasures = NULL; struct GNUNET_TIME_Timestamp expiration_time = GNUNET_TIME_relative_to_timestamp (ds->expiration_delay); - const char *new_measure = NULL; + const char *new_measures = NULL; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_array_const ("rules", &jrules), @@ -158,8 +158,8 @@ take_aml_decision_run (void *cls, &jmeasures), NULL), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("new_measure", - &new_measure), + GNUNET_JSON_spec_string ("new_measures", + &new_measures), NULL), GNUNET_JSON_spec_end () }; @@ -350,13 +350,14 @@ take_aml_decision_run (void *cls, } GNUNET_assert (off == num_measures); - ds->dh = TALER_EXCHANGE_add_aml_decision ( + ds->dh = TALER_EXCHANGE_post_aml_decision ( TALER_TESTING_interpreter_get_context (is), exchange_url, h_payto, + NULL, /* payto_uri */ now, ds->successor_measure, - new_measure, + new_measures, expiration_time, num_rules, rules, @@ -368,9 +369,9 @@ take_aml_decision_run (void *cls, officer_priv, &take_aml_decision_cb, ds); - for (unsigned int i = 0; i<num_rules; i++) + for (unsigned int j = 0; j<num_rules; j++) { - struct TALER_EXCHANGE_AccountRule *rule = &rules[i]; + struct TALER_EXCHANGE_AccountRule *rule = &rules[j]; GNUNET_free (rule->measures); } @@ -402,7 +403,7 @@ take_aml_decision_cleanup (void *cls, { TALER_TESTING_command_incomplete (ds->is, cmd->label); - TALER_EXCHANGE_add_aml_decision_cancel (ds->dh); + TALER_EXCHANGE_post_aml_decision_cancel (ds->dh); ds->dh = NULL; } json_decref (ds->new_rules); diff --git a/src/testing/testing_api_cmd_twister_exec_client.c b/src/testing/testing_api_cmd_twister_exec_client.c index bf83c1f80..eccd8b23a 100644 --- a/src/testing/testing_api_cmd_twister_exec_client.c +++ b/src/testing/testing_api_cmd_twister_exec_client.c @@ -523,16 +523,17 @@ TALER_TESTING_cmd_delete_object (const char *label, dos = GNUNET_new (struct DeleteObjectState); dos->path = path; dos->config_filename = config_filename; + { + struct TALER_TESTING_Command cmd = { + .label = label, + .run = &delete_object_run, + .cleanup = &delete_object_cleanup, + .traits = &delete_object_traits, + .cls = dos + }; - struct TALER_TESTING_Command cmd = { - .label = label, - .run = &delete_object_run, - .cleanup = &delete_object_cleanup, - .traits = &delete_object_traits, - .cls = dos - }; - - return cmd; + return cmd; + } } @@ -901,17 +902,17 @@ TALER_TESTING_cmd_malform_response (const char *label, mrs = GNUNET_new (struct MalformResponseState); mrs->config_filename = config_filename; + { + struct TALER_TESTING_Command cmd = { + .label = label, + .run = &malform_response_run, + .cleanup = &malform_response_cleanup, + .traits = &malform_response_traits, + .cls = mrs + }; - struct TALER_TESTING_Command cmd = { - .label = label, - .run = &malform_response_run, - .cleanup = &malform_response_cleanup, - .traits = &malform_response_traits, - .cls = mrs - }; - - return cmd; - + return cmd; + } } diff --git a/src/testing/testing_api_loop.c b/src/testing/testing_api_loop.c index 958b3b5df..89c966f26 100644 --- a/src/testing/testing_api_loop.c +++ b/src/testing/testing_api_loop.c @@ -156,7 +156,7 @@ TALER_TESTING_interpreter_get_command (struct TALER_TESTING_Interpreter *is, cmd = GNUNET_CONTAINER_multihashmap_get (is->vars, &h_name); if (NULL == cmd) - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Command not found by name: %s\n", name); return cmd; @@ -264,6 +264,30 @@ TALER_TESTING_interpreter_get_current_label ( } +void +TALER_TESTING_update_variables_ ( + struct TALER_TESTING_Interpreter *is, + struct TALER_TESTING_Command *cmd) +{ + struct GNUNET_HashCode h_name; + + if (NULL == cmd->name) + return; + GNUNET_CRYPTO_hash (cmd->name, + strlen (cmd->name), + &h_name); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Storing command %s under variable `%s'\n", + cmd->label, + cmd->name); + (void) GNUNET_CONTAINER_multihashmap_put ( + is->vars, + &h_name, + cmd, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); +} + + static void interpreter_run (void *cls) { @@ -288,20 +312,9 @@ interpreter_run (void *cls) = GNUNET_TIME_absolute_get (); if (0 == cmd->num_tries) cmd->start_time = cmd->last_req_time; - cmd->num_tries = 1; - if (NULL != cmd->name) - { - struct GNUNET_HashCode h_name; - - GNUNET_CRYPTO_hash (cmd->name, - strlen (cmd->name), - &h_name); - (void) GNUNET_CONTAINER_multihashmap_put ( - is->vars, - &h_name, - cmd, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); - } + cmd->num_tries++; + TALER_TESTING_update_variables_ (is, + cmd); cmd->run (cmd->cls, cmd, is); @@ -829,14 +842,15 @@ rewind_ip_run (void *cls, NULL != is->commands[new_ip].label; new_ip++) { - const struct TALER_TESTING_Command *cmd = &is->commands[new_ip]; + const struct TALER_TESTING_Command *ipcmd + = &is->commands[new_ip]; - if (cmd == target) + if (ipcmd == target) break; - if (TALER_TESTING_cmd_is_batch (cmd)) + if (TALER_TESTING_cmd_is_batch (ipcmd)) { int ret = seek_batch (is, - cmd, + ipcmd, target); if (GNUNET_SYSERR == ret) return; /* failure! */ diff --git a/src/testing/testing_api_twister_helpers.c b/src/testing/testing_api_twister_helpers.c index 68fbf0082..d5f61e87c 100644 --- a/src/testing/testing_api_twister_helpers.c +++ b/src/testing/testing_api_twister_helpers.c @@ -23,11 +23,11 @@ * @author Christian Grothoff * @author Marcello Stanisci */ - #include "platform.h" #include <gnunet/gnunet_util_lib.h> #include "taler_twister_testing_lib.h" + /** * Prepare twister for execution; mainly checks whether the * HTTP port is available and construct the base URL based on it. diff --git a/src/util/amount.c b/src/util/amount.c index d102b4d94..2722da81a 100644 --- a/src/util/amount.c +++ b/src/util/amount.c @@ -243,17 +243,23 @@ enum GNUNET_GenericReturnValue TALER_amount_set_zero (const char *cur, struct TALER_Amount *amount) { + char tmp[TALER_CURRENCY_LEN]; size_t slen; if (GNUNET_OK != TALER_check_currency (cur)) return GNUNET_SYSERR; slen = strlen (cur); + /* make a copy of 'cur' to 'tmp' as the memset may clobber cur + if cur aliases &amount->currency! */ + memcpy (tmp, + cur, + slen); memset (amount, 0, sizeof (struct TALER_Amount)); for (unsigned int i = 0; i<slen; i++) - amount->currency[i] = cur[i]; + amount->currency[i] = tmp[i]; return GNUNET_OK; } @@ -293,6 +299,29 @@ TALER_amount_max (struct TALER_Amount *ma, } +enum GNUNET_GenericReturnValue +TALER_amount_min (struct TALER_Amount *mi, + const struct TALER_Amount *a1, + const struct TALER_Amount *a2) +{ + if (GNUNET_OK != + TALER_amount_cmp_currency (a1, + a2)) + { + memset (mi, + 0, + sizeof (*mi)); + return GNUNET_SYSERR; + } + if (1 == TALER_amount_cmp (a1, + a2)) + *mi = *a2; + else + *mi = *a1; + return GNUNET_OK; +} + + bool TALER_amount_is_zero (const struct TALER_Amount *amount) { diff --git a/src/util/crypto_confirmation.c b/src/util/crypto_confirmation.c index 99552f150..ee043404f 100644 --- a/src/util/crypto_confirmation.c +++ b/src/util/crypto_confirmation.c @@ -29,7 +29,7 @@ * How long is a TOTP code valid? */ #define TOTP_VALIDITY_PERIOD GNUNET_TIME_relative_multiply ( \ - GNUNET_TIME_UNIT_SECONDS, 30) + GNUNET_TIME_UNIT_SECONDS, 30) /** * Range of time we allow (plus-minus). @@ -132,6 +132,7 @@ TALER_rfc3548_base32decode (const char *val, { if ((rpos < val_size) && (vbit < 8)) { + const char *p; char c = val[rpos++]; if (c == '=') @@ -144,7 +145,7 @@ TALER_rfc3548_base32decode (const char *val, break; /* Ok, 2x '=' padding is allowed */ return -1; /* invalid padding */ } - const char *p = strchr (decTable__, toupper (c)); + p = strchr (decTable__, toupper (c)); if (! p) { /* invalid character */ diff --git a/src/util/crypto_contract.c b/src/util/crypto_contract.c index bec34c983..8656af766 100644 --- a/src/util/crypto_contract.c +++ b/src/util/crypto_contract.c @@ -459,12 +459,6 @@ TALER_CRYPTO_contract_decrypt_for_deposit ( size_t econtract_size) { const struct TALER_PurseContractPublicKeyP *purse_pub = econtract; - - if (econtract_size < sizeof (*purse_pub)) - { - GNUNET_break_op (0); - return NULL; - } struct GNUNET_HashCode key; void *xhdr; size_t hdr_size; @@ -474,6 +468,11 @@ TALER_CRYPTO_contract_decrypt_for_deposit ( json_error_t json_error; json_t *ret; + if (econtract_size < sizeof (*purse_pub)) + { + GNUNET_break_op (0); + return NULL; + } if (GNUNET_OK != GNUNET_CRYPTO_ecdh_eddsa (&contract_priv->ecdhe_priv, &purse_pub->eddsa_pub, diff --git a/src/util/crypto_helper_common.c b/src/util/crypto_helper_common.c index 9eddb7dcb..d39b61933 100644 --- a/src/util/crypto_helper_common.c +++ b/src/util/crypto_helper_common.c @@ -21,6 +21,7 @@ #include "platform.h" #include "taler_util.h" #include "taler_signatures.h" +#include "crypto_helper_common.h" enum GNUNET_GenericReturnValue diff --git a/src/util/crypto_helper_cs.c b/src/util/crypto_helper_cs.c index 4c4a56feb..d423ae640 100644 --- a/src/util/crypto_helper_cs.c +++ b/src/util/crypto_helper_cs.c @@ -534,7 +534,7 @@ more: const struct TALER_CRYPTO_SignFailure *sf = (const struct TALER_CRYPTO_SignFailure *) buf; - ec = (enum TALER_ErrorCode) ntohl (sf->ec); + ec = (enum TALER_ErrorCode) (int) ntohl (sf->ec); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Signing failed with status %d!\n", ec); @@ -757,7 +757,7 @@ more: const struct TALER_CRYPTO_RDeriveFailure *rdf = (const struct TALER_CRYPTO_RDeriveFailure *) buf; - ec = (enum TALER_ErrorCode) ntohl (rdf->ec); + ec = (enum TALER_ErrorCode) (int) ntohl (rdf->ec); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "R derivation failed!\n"); finished = true; @@ -995,7 +995,7 @@ more: const struct TALER_CRYPTO_SignFailure *sf = (const struct TALER_CRYPTO_SignFailure *) buf; - ec = (enum TALER_ErrorCode) ntohl (sf->ec); + ec = (enum TALER_ErrorCode) (int) ntohl (sf->ec); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Signing %u failed with status %d!\n", wpos, @@ -1238,7 +1238,7 @@ more: const struct TALER_CRYPTO_RDeriveFailure *rdf = (const struct TALER_CRYPTO_RDeriveFailure *) buf; - ec = (enum TALER_ErrorCode) ntohl (rdf->ec); + ec = (enum TALER_ErrorCode) (int) ntohl (rdf->ec); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "R derivation %u failed with status %d!\n", wpos, diff --git a/src/util/crypto_helper_esign.c b/src/util/crypto_helper_esign.c index e044d31d1..4c46cec56 100644 --- a/src/util/crypto_helper_esign.c +++ b/src/util/crypto_helper_esign.c @@ -466,7 +466,7 @@ more: (const struct TALER_CRYPTO_EddsaSignFailure *) buf; finished = true; - ec = (enum TALER_ErrorCode) ntohl (sf->ec); + ec = (enum TALER_ErrorCode) (int) ntohl (sf->ec); break; } case TALER_HELPER_EDDSA_MT_AVAIL: diff --git a/src/util/crypto_helper_rsa.c b/src/util/crypto_helper_rsa.c index e23e12a88..df14c9100 100644 --- a/src/util/crypto_helper_rsa.c +++ b/src/util/crypto_helper_rsa.c @@ -21,9 +21,9 @@ #include "platform.h" #include "taler_util.h" #include "taler_signatures.h" +#include "crypto_helper_common.h" #include "taler-exchange-secmod-rsa.h" #include <poll.h> -#include "crypto_helper_common.h" struct TALER_CRYPTO_RsaDenominationHelper @@ -553,7 +553,7 @@ more: const struct TALER_CRYPTO_SignFailure *sf = (const struct TALER_CRYPTO_SignFailure *) buf; - ec = (enum TALER_ErrorCode) ntohl (sf->ec); + ec = (enum TALER_ErrorCode) (int) ntohl (sf->ec); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Signing failed!\n"); finished = true; @@ -808,7 +808,7 @@ more: const struct TALER_CRYPTO_SignFailure *sf = (const struct TALER_CRYPTO_SignFailure *) buf; - ec = (enum TALER_ErrorCode) ntohl (sf->ec); + ec = (enum TALER_ErrorCode) (int) ntohl (sf->ec); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Signing %u failed with status %d!\n", wpos, diff --git a/src/util/iban.c b/src/util/iban.c index c2274d3cb..8d1e898cb 100644 --- a/src/util/iban.c +++ b/src/util/iban.c @@ -223,7 +223,6 @@ TALER_iban_validate (const char *iban) char *nbuf; unsigned long long dividend; unsigned long long remainder; - unsigned int i; unsigned int j; if (NULL == iban) @@ -255,7 +254,8 @@ TALER_iban_validate (const char *iban) return msg; } nbuf = GNUNET_malloc ((len * 2) + 1); - for (i = 0, j = 0; i < len; i++) + j = 0; + for (unsigned int i = 0; i < len; i++) { if (isalpha ((unsigned char) ibancpy[i])) { diff --git a/src/util/os_installation.c b/src/util/os_installation.c index 1cbb9e78a..79beba51c 100644 --- a/src/util/os_installation.c +++ b/src/util/os_installation.c @@ -24,7 +24,7 @@ */ #include "platform.h" #include <gnunet/gnunet_util_lib.h> - +#include "taler_util.h" /** * Default project data used for installation path detection @@ -44,6 +44,7 @@ static const struct GNUNET_OS_ProjectData taler_pd = { .is_gnu = 1, .gettext_domain = "taler", .gettext_path = NULL, + .agpl_url = "https://git.taler.net/" }; diff --git a/src/util/payto.c b/src/util/payto.c index a471175a9..528108efa 100644 --- a/src/util/payto.c +++ b/src/util/payto.c @@ -347,8 +347,6 @@ TALER_payto_validate (const char *payto_uri) if (NULL == strchr (ALLOWED_CHARACTERS, (int) payto_uri[i])) { - char *ret; - GNUNET_asprintf (&ret, "Encountered invalid character `%c' at offset %u in payto URI `%s'", payto_uri[i], diff --git a/src/util/secmod_common.c b/src/util/secmod_common.c index 87ce17e06..3156b15c4 100644 --- a/src/util/secmod_common.c +++ b/src/util/secmod_common.c @@ -133,7 +133,7 @@ TES_transmit (int sock, struct GNUNET_NETWORK_Handle * -TES_open_socket (const char *unixpath) +TES_open_socket (const char *my_unixpath) { int sock; mode_t old_umask; @@ -159,25 +159,25 @@ TES_open_socket (const char *unixpath) struct sockaddr_un un; if (GNUNET_OK != - GNUNET_DISK_directory_create_for_file (unixpath)) + GNUNET_DISK_directory_create_for_file (my_unixpath)) { GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "mkdir(dirname)", - unixpath); + my_unixpath); } - if (0 != unlink (unixpath)) + if (0 != unlink (my_unixpath)) { if (ENOENT != errno) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", - unixpath); + my_unixpath); } memset (&un, 0, sizeof (un)); un.sun_family = AF_UNIX; strncpy (un.sun_path, - unixpath, + my_unixpath, sizeof (un.sun_path) - 1); if (0 != bind (sock, (const struct sockaddr *) &un, @@ -185,7 +185,7 @@ TES_open_socket (const char *unixpath) { GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "bind", - unixpath); + my_unixpath); GNUNET_break (0 == close (sock)); goto cleanup; } @@ -196,7 +196,7 @@ TES_open_socket (const char *unixpath) { GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "listen", - unixpath); + my_unixpath); GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ret)); ret = NULL; @@ -218,14 +218,17 @@ TES_wake_clients (void) NULL != client; client = client->next) { - GNUNET_assert (sizeof (num) == #ifdef __linux__ + GNUNET_assert (sizeof (num) == write (client->esock, + &num, + sizeof (num))); #else + GNUNET_assert (sizeof (num) == write (client->esock_in, -#endif &num, sizeof (num))); +#endif } GNUNET_assert (0 == pthread_mutex_unlock (&TES_clients_lock)); } @@ -249,7 +252,7 @@ TES_read_work (void *cls, recv_size = recv (client->csock, &buf[off], sizeof (client->iobuf) - off, - 0); + 0); if (-1 == recv_size) { if ( (0 == off) && @@ -334,23 +337,27 @@ TES_await_ready (struct TES_Client *client) "poll"); for (int i = 0; i<2; i++) { + if ( #ifdef __linux__ - if ( (pfds[i].fd == client->esock) && + (pfds[i].fd == client->esock) && #else - if ( (pfds[i].fd == client->esock_out) && + (pfds[i].fd == client->esock_out) && #endif - (POLLIN == pfds[i].revents) ) + (POLLIN == pfds[i].revents) ) { uint64_t num; - GNUNET_assert (sizeof (num) == #ifdef __linux__ + GNUNET_assert (sizeof (num) == read (client->esock, + &num, + sizeof (num))); #else + GNUNET_assert (sizeof (num) == read (client->esock_out, -#endif &num, sizeof (num))); +#endif return true; } } diff --git a/src/util/taler-config.c b/src/util/taler-config.c index 0e432f852..e4ff22767 100644 --- a/src/util/taler-config.c +++ b/src/util/taler-config.c @@ -47,10 +47,6 @@ main (int argc, }; enum GNUNET_GenericReturnValue ret; - if (GNUNET_OK != - GNUNET_STRINGS_get_utf8_args (argc, argv, - &argc, &argv)) - return EXIT_FAILURE; TALER_OS_init (); ret = GNUNET_PROGRAM_run (argc, argv, @@ -60,7 +56,6 @@ main (int argc, options, &GNUNET_CONFIGURATION_config_tool_run, &cs); - GNUNET_free_nz ((void *) argv); GNUNET_CONFIGURATION_config_settings_free (&cs); if (GNUNET_NO == ret) return 0; diff --git a/src/util/taler-exchange-secmod-cs.c b/src/util/taler-exchange-secmod-cs.c index 3e9ba1558..f69acd890 100644 --- a/src/util/taler-exchange-secmod-cs.c +++ b/src/util/taler-exchange-secmod-cs.c @@ -327,13 +327,13 @@ static int global_ret; * Time when the key update is executed. * Either the actual current time, or a pretended time. */ -static struct GNUNET_TIME_Timestamp now; +static struct GNUNET_TIME_Timestamp global_now; /** * The time for the key update, as passed by the user * on the command line. */ -static struct GNUNET_TIME_Timestamp now_tmp; +static struct GNUNET_TIME_Timestamp global_now_tmp; /** * Where do we store the keys? @@ -1107,7 +1107,8 @@ setup_key (struct DenominationKey *dk, keydir, denom->section, (unsigned long long) (dk->anchor.abs_time.abs_value_us - / GNUNET_TIME_UNIT_SECONDS.rel_value_us)); + / GNUNET_TIME_UNIT_SECONDS.rel_value_us + )); if (GNUNET_OK != GNUNET_DISK_fn_write (dk->filename, &priv, @@ -2185,15 +2186,17 @@ run (void *cls, (void) cls; (void) args; (void) cfgfile; - if (GNUNET_TIME_timestamp_cmp (now, !=, now_tmp)) + if (GNUNET_TIME_timestamp_cmp (global_now, + !=, + global_now_tmp)) { /* The user gave "--now", use it! */ - now = now_tmp; + global_now = global_now_tmp; } else { /* get current time again, we may be timetraveling! */ - now = GNUNET_TIME_timestamp_get (); + global_now = GNUNET_TIME_timestamp_get (); } GNUNET_asprintf (&secname, "%s-secmod-cs", @@ -2211,24 +2214,17 @@ run (void *cls, global_ret = EXIT_NOTCONFIGURED; return; } - GNUNET_free (secname); if (GNUNET_OK != load_durations (cfg)) { global_ret = EXIT_NOTCONFIGURED; - return; - } - { - char *secname; - - GNUNET_asprintf (&secname, - "%s-secmod-cs", - section); - global_ret = TES_listen_start (cfg, - secname, - &cb); GNUNET_free (secname); + return; } + global_ret = TES_listen_start (cfg, + secname, + &cb); + GNUNET_free (secname); if (0 != global_ret) return; sem_init (&worker_sem, @@ -2258,7 +2254,7 @@ run (void *cls, struct LoadContext lc = { .cfg = cfg, .ret = GNUNET_OK, - .t = now + .t = global_now }; GNUNET_assert (0 == pthread_mutex_lock (&keys_lock)); @@ -2312,7 +2308,7 @@ main (int argc, "time", "TIMESTAMP", "pretend it is a different time for the update", - &now_tmp), + &global_now_tmp), GNUNET_GETOPT_option_uint ('w', "workers", "COUNT", @@ -2329,7 +2325,9 @@ main (int argc, not do this, the linker may "optimize" libtalerutil away and skip #TALER_OS_init(), which we do need */ TALER_OS_init (); - now_tmp = now = GNUNET_TIME_timestamp_get (); + global_now_tmp + = global_now + = GNUNET_TIME_timestamp_get (); ret = GNUNET_PROGRAM_run (argc, argv, "taler-exchange-secmod-cs", "Handle private CS key operations for a Taler exchange", diff --git a/src/util/taler-exchange-secmod-eddsa.c b/src/util/taler-exchange-secmod-eddsa.c index 0b95447f7..401ac5835 100644 --- a/src/util/taler-exchange-secmod-eddsa.c +++ b/src/util/taler-exchange-secmod-eddsa.c @@ -371,7 +371,8 @@ setup_key (struct Key *key, "%s/%llu", keydir, (unsigned long long) (key->anchor.abs_time.abs_value_us - / GNUNET_TIME_UNIT_SECONDS.rel_value_us)); + / GNUNET_TIME_UNIT_SECONDS.rel_value_us + )); if (GNUNET_OK != GNUNET_DISK_fn_write (key->filename, &priv, @@ -1118,20 +1119,11 @@ run (void *cls, global_ret = EXIT_NOTCONFIGURED; return; } - GNUNET_free (secname); GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); - { - char *secname; - - GNUNET_asprintf (&secname, - "%s-secmod-eddsa", - section); - global_ret = TES_listen_start (cfg, - secname, - &cb); - GNUNET_free (secname); - } + global_ret = TES_listen_start (cfg, + secname, + &cb); if (0 != global_ret) return; /* Load keys */ diff --git a/src/util/taler-exchange-secmod-rsa.c b/src/util/taler-exchange-secmod-rsa.c index c80e2e3c4..6be78b20e 100644 --- a/src/util/taler-exchange-secmod-rsa.c +++ b/src/util/taler-exchange-secmod-rsa.c @@ -294,13 +294,13 @@ static int global_ret; * Time when the key update is executed. * Either the actual current time, or a pretended time. */ -static struct GNUNET_TIME_Timestamp now; +static struct GNUNET_TIME_Timestamp global_now; /** * The time for the key update, as passed by the user * on the command line. */ -static struct GNUNET_TIME_Timestamp now_tmp; +static struct GNUNET_TIME_Timestamp global_now_tmp; /** * Where do we store the keys? @@ -893,7 +893,8 @@ setup_key (struct DenominationKey *dk, keydir, denom->section, (unsigned long long) (dk->anchor.abs_time.abs_value_us - / GNUNET_TIME_UNIT_SECONDS.rel_value_us)); + / GNUNET_TIME_UNIT_SECONDS.rel_value_us + )); if (GNUNET_OK != GNUNET_DISK_fn_write (dk->filename, buf, @@ -1973,15 +1974,17 @@ run (void *cls, (void) cls; (void) args; (void) cfgfile; - if (GNUNET_TIME_timestamp_cmp (now, !=, now_tmp)) + if (GNUNET_TIME_timestamp_cmp (global_now, + !=, + global_now_tmp)) { /* The user gave "--now", use it! */ - now = now_tmp; + global_now = global_now_tmp; } else { /* get current time again, we may be timetraveling! */ - now = GNUNET_TIME_timestamp_get (); + global_now = GNUNET_TIME_timestamp_get (); } GNUNET_asprintf (&secname, "%s-secmod-rsa", @@ -1999,24 +2002,20 @@ run (void *cls, global_ret = EXIT_NOTCONFIGURED; return; } - GNUNET_free (secname); if (GNUNET_OK != load_durations (cfg)) { global_ret = EXIT_NOTCONFIGURED; - return; - } - { - char *secname; - - GNUNET_asprintf (&secname, - "%s-secmod-rsa", - section); - global_ret = TES_listen_start (cfg, - secname, - &cb); GNUNET_free (secname); + return; } + GNUNET_asprintf (&secname, + "%s-secmod-rsa", + section); + global_ret = TES_listen_start (cfg, + secname, + &cb); + GNUNET_free (secname); if (0 != global_ret) return; sem_init (&worker_sem, @@ -2047,7 +2046,7 @@ run (void *cls, struct LoadContext lc = { .cfg = cfg, .ret = GNUNET_OK, - .t = now + .t = global_now }; GNUNET_assert (0 == pthread_mutex_lock (&keys_lock)); @@ -2101,7 +2100,7 @@ main (int argc, "time", "TIMESTAMP", "pretend it is a different time for the update", - &now_tmp), + &global_now_tmp), GNUNET_GETOPT_option_uint ('w', "workers", "COUNT", @@ -2118,7 +2117,9 @@ main (int argc, not do this, the linker may "optimize" libtalerutil away and skip #TALER_OS_init(), which we do need */ TALER_OS_init (); - now_tmp = now = GNUNET_TIME_timestamp_get (); + global_now_tmp + = global_now + = GNUNET_TIME_timestamp_get (); ret = GNUNET_PROGRAM_run (argc, argv, "taler-exchange-secmod-rsa", "Handle private RSA key operations for a Taler exchange", diff --git a/src/util/test_age_restriction.c b/src/util/test_age_restriction.c index 61499e5e0..0d87926d4 100644 --- a/src/util/test_age_restriction.c +++ b/src/util/test_age_restriction.c @@ -30,7 +30,7 @@ * @return String representation of the age mask, allocated by GNUNET_malloc. * Can be used as value in the TALER config. */ -char * +static char * age_mask_to_string ( const struct TALER_AgeMask *m) { @@ -68,7 +68,7 @@ age_mask_to_string ( } -enum GNUNET_GenericReturnValue +static enum GNUNET_GenericReturnValue test_groups (void) { struct @@ -129,7 +129,7 @@ test_groups (void) } -enum GNUNET_GenericReturnValue +static enum GNUNET_GenericReturnValue test_dates (void) { struct TALER_AgeMask mask = { @@ -137,7 +137,7 @@ test_dates (void) }; struct { - char *date; + const char *date; uint32_t expected; enum GNUNET_GenericReturnValue ret; } @@ -174,7 +174,7 @@ test_dates (void) { uint32_t d; enum GNUNET_GenericReturnValue ret; - char *date = test[t].date; + const char *date = test[t].date; if (NULL == test[t].date) { @@ -224,7 +224,7 @@ test_dates (void) } -enum GNUNET_GenericReturnValue +static enum GNUNET_GenericReturnValue test_lowest (void) { struct TALER_AgeMask mask = { @@ -270,7 +270,7 @@ test_lowest (void) } -enum GNUNET_GenericReturnValue +static enum GNUNET_GenericReturnValue test_adult (void) { struct { struct TALER_AgeMask mask; uint8_t expected; } @@ -304,7 +304,8 @@ static struct TALER_AgeMask age_mask = { .bits = 1 | 1 << 8 | 1 << 10 | 1 << 12 | 1 << 14 | 1 << 16 | 1 << 18 | 1 << 21 }; -enum GNUNET_GenericReturnValue + +static enum GNUNET_GenericReturnValue test_attestation (void) { uint8_t age; diff --git a/src/util/test_payto.c b/src/util/test_payto.c index fc800c8d2..c01969161 100644 --- a/src/util/test_payto.c +++ b/src/util/test_payto.c @@ -46,6 +46,8 @@ main (int argc, GNUNET_log_setup ("test-payto", "WARNING", NULL); + GNUNET_assert (GNUNET_TIME_absolute_is_never ( + GNUNET_TIME_UNIT_FOREVER_TS.abs_time)); GNUNET_assert (NULL == TALER_iban_validate ("FR1420041010050500013M02606")); GNUNET_assert (NULL == diff --git a/src/util/test_url.c b/src/util/test_url.c index 029302993..f5e6ff4ee 100644 --- a/src/util/test_url.c +++ b/src/util/test_url.c @@ -30,11 +30,15 @@ * @param expected expected input */ static void -cf (char *input, char *expected) +cf (char *input, + const char *expected) { - if (0 != strcmp (input, expected)) + if (0 != strcmp (input, + expected)) { - printf ("got '%s' but expected '%s'\n", input, expected); + printf ("got '%s' but expected '%s'\n", + input, + expected); GNUNET_assert (0); } GNUNET_free (input); diff --git a/src/util/tokens.c b/src/util/tokens.c index 5d99c5dfe..c9f68448f 100644 --- a/src/util/tokens.c +++ b/src/util/tokens.c @@ -176,7 +176,7 @@ TALER_token_blind_input_copy (struct TALER_TokenUseMerchantValues *bi_dst, enum GNUNET_GenericReturnValue TALER_token_issue_sign (const struct TALER_TokenIssuePrivateKeyP *issue_priv, - const struct TALER_TokenEnvelopeP *envelope, + const struct TALER_TokenEnvelope *envelope, struct TALER_TokenIssueBlindSignatureP *issue_sig) { issue_sig->signature @@ -188,6 +188,7 @@ TALER_token_issue_sign (const struct TALER_TokenIssuePrivateKeyP *issue_priv, return GNUNET_OK; } + enum GNUNET_GenericReturnValue TALER_token_issue_verify (const struct TALER_TokenUsePublicKeyP *use_pub, const struct TALER_TokenIssuePublicKeyP *issue_pub, @@ -211,6 +212,7 @@ TALER_token_issue_verify (const struct TALER_TokenUsePublicKeyP *use_pub, return GNUNET_OK; } + enum GNUNET_GenericReturnValue TALER_token_issue_sig_unblind ( struct TALER_TokenIssueSignatureP *issue_sig, @@ -221,16 +223,16 @@ TALER_token_issue_sig_unblind ( const struct TALER_TokenIssuePublicKeyP *issue_pub) { issue_sig->signature - = GNUNET_CRYPTO_blind_sig_unblind (blinded_sig->signature, - secret, - &use_pub_hash->hash, - sizeof (use_pub_hash->hash), - alg_values->blinding_inputs, - issue_pub->public_key); + = GNUNET_CRYPTO_blind_sig_unblind (blinded_sig->signature, + secret, + &use_pub_hash->hash, + sizeof (use_pub_hash->hash), + alg_values->blinding_inputs, + issue_pub->public_key); if (NULL == issue_sig->signature) { GNUNET_break_op (0); return GNUNET_SYSERR; } return GNUNET_OK; -}
\ No newline at end of file +} |