aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Blättler <blatc2@bfh.ch>2023-12-10 14:42:02 +0100
committerChristian Blättler <blatc2@bfh.ch>2023-12-10 14:42:02 +0100
commit62448125fbffb3bdd50fb5b5abc0d25e2449f8c6 (patch)
tree96a9381533384b1498eb642c5a9cbece52a385ce
parentf99262923121d5c0e1b995e325d97830110f5ce5 (diff)
parentcfdbc9a3c3fba99982beaf156794cb51494e0c3f (diff)
downloadexchange-62448125fbffb3bdd50fb5b5abc0d25e2449f8c6.tar.xz
Merge branch 'master' into feature/tokens
-rwxr-xr-xcontrib/taler-exchange-dbconfig105
-rw-r--r--debian/changelog7
-rw-r--r--debian/control4
-rw-r--r--debian/libtalerexchange.postinst28
-rw-r--r--src/bank-lib/fakebank_tbi.c39
-rw-r--r--src/bank-lib/fakebank_tbr_get_history.c2
-rw-r--r--src/bank-lib/fakebank_twg_history.c4
-rw-r--r--src/exchange/taler-exchange-httpd_batch-deposit.c50
-rw-r--r--src/exchange/taler-exchange-httpd_db.c11
-rw-r--r--src/exchange/taler-exchange-httpd_extensions.c44
-rw-r--r--src/exchange/taler-exchange-httpd_responses.c22
-rw-r--r--src/exchange/taler-exchange-httpd_responses.h21
-rw-r--r--src/exchangedb/exchange_do_deposit.sql1
-rw-r--r--src/exchangedb/exchange_do_insert_or_update_policy_details.sql6
-rw-r--r--src/exchangedb/pg_add_policy_fulfillment_proof.c10
-rw-r--r--src/exchangedb/pg_do_deposit.c1
-rw-r--r--src/include/taler_extensions_policy.h2
-rw-r--r--src/kyclogic/Makefile.am1
-rw-r--r--src/lib/Makefile.am1
-rwxr-xr-xsrc/testing/taler-unified-setup.sh6
-rw-r--r--src/util/Makefile.am1
-rw-r--r--src/util/exchange_signatures.c3
22 files changed, 291 insertions, 78 deletions
diff --git a/contrib/taler-exchange-dbconfig b/contrib/taler-exchange-dbconfig
index c4790f823..eb90ee721 100755
--- a/contrib/taler-exchange-dbconfig
+++ b/contrib/taler-exchange-dbconfig
@@ -24,35 +24,25 @@ SKIP_DBINIT=0
FORCE_PERMS=0
DBUSER="taler-exchange-httpd"
DBGROUP="taler-exchange-db"
-DBNAME="exchange"
CFGFILE="/etc/taler/taler.conf"
-DBCFGFILE="/etc/taler/secrets/exchange-db.secret.conf"
# Parse command-line options
-while getopts 'c:d:g:hn:prsu:' OPTION; do
+while getopts 'c:g:hprsu:' OPTION; do
case "$OPTION" in
c)
CFGFILE="$OPTARG"
;;
- d)
- DBCFGFILE="$OPTARG"
- ;;
h)
echo 'Supported options:'
- echo " -c FILENAME -- write configuration to FILENAME (default: $CFGFILE)"
- echo " -d FILENAME -- write database access configuration to FILENAME (default: $DBCFGFILE)"
+ echo " -c FILENAME -- use configuration FILENAME (default: $CFGFILE)"
echo " -g GROUP -- taler-exchange to be run by GROUP (default: $DBGROUP)"
echo " -h -- print this help text"
- echo " -n NAME -- user NAME for database name (default: $DBNAME)"
echo " -r -- reset database (dangerous)"
echo " -p -- force permission setup even without database initialization"
echo " -s -- skip database initialization"
echo " -u USER -- taler-exchange to be run by USER (default: $DBUSER)"
exit 0
;;
- n)
- DBNAME="$OPTARG"
- ;;
p)
FORCE_PERMS="1"
;;
@@ -100,19 +90,6 @@ then
exit 1
fi
-if sudo -i -u postgres psql "$DBNAME" < /dev/null 2> /dev/null
-then
- if [ 1 = "$RESET_DB" ]
- then
- echo "Deleting existing database '$DBNAME'." 1>&2
- sudo -i -u postgres dropdb "$DBNAME"
- else
- echo "Database '$DBNAME' already exists, refusing to setup again."
- echo "Use -r to delete the existing database first (dangerous!)."
- exit 77
- fi
-fi
-
echo "Setting up database user '$DBUSER'." 1>&2
if ! sudo -i -u postgres createuser "$DBUSER" 2> /dev/null
@@ -120,32 +97,60 @@ then
echo "Database user '$DBUSER' already existed. Continuing anyway." 1>&2
fi
-echo "Creating database '$DBNAME'." 1>&2
+DBPATH=$(taler-config \
+ -c "$CFGFILE" \
+ -s exchangedb-postgres \
+ -o CONFIG)
-if ! sudo -i -u postgres createdb -O "$DBUSER" "$DBNAME"
+if ! echo "$DBPATH" | grep "postgres://" > /dev/null
then
- echo "Failed to create database '$DBNAME'"
+ echo "Invalid database configuration value '$DBPATH'." 1>&2
exit 1
fi
-if [ -f "$DBCFGFILE" ]
+DBNAME=$(echo "$DBPATH" \
+ | sed \
+ -e "s/postgres:\/\/.*\///" \
+ -e "s/?.*//")
+
+if sudo -i -u postgres psql "$DBNAME" < /dev/null 2> /dev/null
then
- echo "Adding database configuration to '$DBCFGFILE'." 1>&2
- echo -e "[exchangedb-postgres]\nCONFIG=postgres:///$DBNAME\n" >> "$DBCFGFILE"
- chown root:"$DBGROUP" "$DBCFGFILE"
- chmod 640 "$CFGFILE"
+ if [ 1 = "$RESET_DB" ]
+ then
+ echo "Deleting existing database '$DBNAME'." 1>&2
+ if ! sudo -i -u postgres dropdb "$DBNAME"
+ then
+ echo "Failed to delete existing database '$DBNAME'"
+ exit 1
+ fi
+ DO_CREATE=1
+ else
+ echo "Database '$DBNAME' already exists, continuing anyway."
+ DO_CREATE=0
+ fi
else
- echo "Configuration '$DBCFGFILE' does not yet exist, creating it." 1>&2
- mkdir -p "$(dirname "$DBCFGFILE")"
- echo -e "[exchangedb-postgres]\nCONFIG=postgres:///$DBNAME\n" >> "$CFGFILE"
- chown root:"$DBGROUP" "$DBCFGFILE"
- chmod 640 "$DBCFGFILE"
+ DO_CREATE=1
+fi
+
+if [ 1 = "$DO_CREATE" ]
+then
+ echo "Creating database '$DBNAME'." 1>&2
+
+ if ! sudo -i -u postgres createdb -O "$DBUSER" "$DBNAME"
+ then
+ echo "Failed to create database '$DBNAME'"
+ exit 1
+ fi
fi
if [ 0 = "$SKIP_DBINIT" ]
then
echo "Initializing database '$DBNAME'." 1>&2
- sudo -u "$DBUSER" "$DBINIT" -c "$CFGFILE"
+ if ! sudo -u "$DBUSER" "$DBINIT" -c "$CFGFILE"
+ then
+ echo "Failed to initialize database schema"
+ exit 1
+ fi
fi
if [ 0 = "$SKIP_DBINIT" ] || [ 1 = "$FORCE_PERMS" ]
@@ -156,16 +161,26 @@ then
do
if [ "$GROUPIE" != "$DBUSER" ]
then
- sudo -u "$DBUSER" \
- echo -e 'GRANT SELECT,INSERT,UPDATE ON ALL TABLES IN SCHEMA exchange TO "'"$GROUPIE"'";\n' \
- 'GRANT USAGE ON ALL SEQUENCES IN SCHEMA exchange TO "'"$GROUPIE"'";\n' \
- | psql taler-exchange
+ if ! sudo -i -u postgres createuser "$GROUPIE" 2> /dev/null
+ then
+ echo "Database user '$GROUPIE' already existed. Continuing anyway." 1>&2
+ fi
+ echo -e 'GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA exchange TO "'"$GROUPIE"'";\n' \
+ 'GRANT USAGE ON ALL SEQUENCES IN SCHEMA exchange TO "'"$GROUPIE"'";\n' \
+ | sudo -u "$DBUSER" psql "$DBNAME"
+ echo -e 'GRANT USAGE ON SCHEMA exchange TO "'"$GROUPIE"'"' \
+ | sudo -u "$DBUSER" psql "$DBNAME"
+ # FIXME: double-check the following GRANTs
+ echo -e 'GRANT USAGE ON SCHEMA _v TO "'"$GROUPIE"'"' \
+ | sudo -u "$DBUSER" psql "$DBNAME"
+ echo -e 'GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA _v TO "'"$GROUPIE"'"' \
+ | sudo -u "$DBUSER" psql "$DBNAME"
+
+
fi
done
fi
-
-
echo "Database configuration finished." 1>&2
exit 0
diff --git a/debian/changelog b/debian/changelog
index c147a0d52..264e99bfc 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+taler-exchange (0.9.3-5) unstable; urgency=low
+
+ * More fixes to the database setup automation scripts.
+ * Implement latest /config API in fakebank.
+
+ -- Christian Grothoff <grothoff@gnu.org> Thu, 7 Dec 2023 00:50:12 -0800
+
taler-exchange (0.9.3-4) unstable; urgency=low
* Minor hot-fixes to the database setup automation script.
diff --git a/debian/control b/debian/control
index 80ebebe69..fe80f9cf8 100644
--- a/debian/control
+++ b/debian/control
@@ -10,7 +10,7 @@ Build-Depends:
gcc-12,
debhelper-compat (= 12),
gettext,
- libgnunet-dev (>=0.20),
+ libgnunet-dev (>=0.21),
libcurl4-gnutls-dev (>=7.35.0) | libcurl4-openssl-dev (>= 7.35.0),
libgcrypt20-dev (>=1.8),
libgnutls28-dev (>=3.2.12),
@@ -146,7 +146,7 @@ Section: libdevel
Architecture: any
Depends:
libtalerexchange (= ${binary:Version}),
- libgnunet-dev (>=0.20),
+ libgnunet-dev (>=0.21),
libgcrypt20-dev (>=1.8),
libmicrohttpd-dev (>=0.9.71),
${misc:Depends},
diff --git a/debian/libtalerexchange.postinst b/debian/libtalerexchange.postinst
new file mode 100644
index 000000000..40b4be061
--- /dev/null
+++ b/debian/libtalerexchange.postinst
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+set -e
+
+. /usr/share/debconf/confmodule
+
+case "${1}" in
+configure)
+
+ if ! dpkg-statoverride --list /etc/taler/taler.conf >/dev/null 2>&1; then
+ dpkg-statoverride --add --update \
+ root root 644 \
+ /etc/taler/taler.conf
+ fi
+
+ ;;
+
+abort-upgrade | abort-remove | abort-deconfigure) ;;
+
+*)
+ echo "postinst called with unknown argument \`${1}'" >&2
+ exit 1
+ ;;
+esac
+
+#DEBHELPER#
+
+exit 0
diff --git a/src/bank-lib/fakebank_tbi.c b/src/bank-lib/fakebank_tbi.c
index 27b930d9f..95e3a8c2e 100644
--- a/src/bank-lib/fakebank_tbi.c
+++ b/src/bank-lib/fakebank_tbi.c
@@ -49,6 +49,11 @@ TALER_FAKEBANK_tbi_main_ (struct TALER_FAKEBANK_Handle *h,
(0 == strcasecmp (method,
MHD_HTTP_METHOD_GET)) )
{
+ struct TALER_Amount zero;
+
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_set_zero (h->currency,
+ &zero));
return TALER_MHD_REPLY_JSON_PACK (
connection,
MHD_HTTP_OK,
@@ -56,6 +61,40 @@ TALER_FAKEBANK_tbi_main_ (struct TALER_FAKEBANK_Handle *h,
"0:0:0"),
GNUNET_JSON_pack_string ("currency",
h->currency),
+ GNUNET_JSON_pack_bool ("allow_conversion",
+ false),
+ GNUNET_JSON_pack_bool ("allow_registrations",
+ true),
+ GNUNET_JSON_pack_bool ("allow_deletions",
+ false),
+ GNUNET_JSON_pack_bool ("allow_edit_name",
+ false),
+ GNUNET_JSON_pack_bool ("allow_edit_cashout_payto_uri",
+ false),
+ TALER_JSON_pack_amount ("default_debit_threshold",
+ &zero),
+ GNUNET_JSON_pack_array_steal ("supported_tan_channels",
+ json_array ()),
+ GNUNET_JSON_pack_object_steal (
+ "currency_specification",
+ GNUNET_JSON_PACK (
+ GNUNET_JSON_pack_string ("name",
+ h->currency),
+ GNUNET_JSON_pack_string ("currency",
+ h->currency),
+ GNUNET_JSON_pack_uint64 ("num_fractional_input_digits",
+ 2),
+ GNUNET_JSON_pack_uint64 ("num_fractional_normal_digits",
+ 2),
+ GNUNET_JSON_pack_uint64 ("num_fractional_trailing_zero_digits",
+ 2),
+ GNUNET_JSON_pack_object_steal (
+ "alt_unit_names",
+ GNUNET_JSON_PACK (
+ GNUNET_JSON_pack_string ("0",
+ h->currency))),
+ GNUNET_JSON_pack_string ("name",
+ h->currency))),
GNUNET_JSON_pack_string ("name",
"taler-bank-integration"));
}
diff --git a/src/bank-lib/fakebank_tbr_get_history.c b/src/bank-lib/fakebank_tbr_get_history.c
index e81e00894..79678636a 100644
--- a/src/bank-lib/fakebank_tbr_get_history.c
+++ b/src/bank-lib/fakebank_tbr_get_history.c
@@ -149,6 +149,7 @@ TALER_FAKEBANK_tbr_get_history_incoming (
if (GNUNET_TIME_relative_is_zero (hc->ha.lp_timeout) &&
(0 < hc->ha.delta))
{
+ acc_payto_uri = hc->acc->payto_uri;
GNUNET_assert (0 ==
pthread_mutex_unlock (&h->big_lock));
if (overflow)
@@ -160,6 +161,7 @@ TALER_FAKEBANK_tbr_get_history_incoming (
}
if (h->in_shutdown)
{
+ acc_payto_uri = hc->acc->payto_uri;
GNUNET_assert (0 ==
pthread_mutex_unlock (&h->big_lock));
goto finish;
diff --git a/src/bank-lib/fakebank_twg_history.c b/src/bank-lib/fakebank_twg_history.c
index 1d70ed127..35cc6587f 100644
--- a/src/bank-lib/fakebank_twg_history.c
+++ b/src/bank-lib/fakebank_twg_history.c
@@ -147,6 +147,7 @@ TALER_FAKEBANK_twg_get_debit_history_ (
if ( (GNUNET_TIME_relative_is_zero (hc->ha.lp_timeout)) &&
(0 < hc->ha.delta))
{
+ acc_payto_uri = hc->acc->payto_uri;
GNUNET_assert (0 ==
pthread_mutex_unlock (&h->big_lock));
if (overflow)
@@ -160,6 +161,7 @@ TALER_FAKEBANK_twg_get_debit_history_ (
}
if (h->in_shutdown)
{
+ acc_payto_uri = hc->acc->payto_uri;
GNUNET_assert (0 ==
pthread_mutex_unlock (&h->big_lock));
goto finish;
@@ -400,6 +402,7 @@ TALER_FAKEBANK_twg_get_credit_history_ (
if (GNUNET_TIME_relative_is_zero (hc->ha.lp_timeout) &&
(0 < hc->ha.delta))
{
+ acc_payto_uri = hc->acc->payto_uri;
GNUNET_assert (0 ==
pthread_mutex_unlock (&h->big_lock));
if (overflow)
@@ -411,6 +414,7 @@ TALER_FAKEBANK_twg_get_credit_history_ (
}
if (h->in_shutdown)
{
+ acc_payto_uri = hc->acc->payto_uri;
GNUNET_assert (0 ==
pthread_mutex_unlock (&h->big_lock));
goto finish;
diff --git a/src/exchange/taler-exchange-httpd_batch-deposit.c b/src/exchange/taler-exchange-httpd_batch-deposit.c
index 9f66a99a4..835a974fc 100644
--- a/src/exchange/taler-exchange-httpd_batch-deposit.c
+++ b/src/exchange/taler-exchange-httpd_batch-deposit.c
@@ -60,16 +60,24 @@ struct BatchDepositContext
*/
struct TALER_EXCHANGEDB_BatchDeposit bd;
+
/**
- * Additional details for policy extension relevant for this
- * deposit operation, possibly NULL!
+ * Total amount that is accumulated with this deposit,
+ * without fee.
*/
- json_t *policy_json;
+ struct TALER_Amount accumulated_total_without_fee;
/**
- * Hash over the merchant's payto://-URI with the wire salt.
+ * True, if no policy was present in the request. Then
+ * @e policy_json is NULL and @e h_policy will be all zero.
*/
- struct TALER_MerchantWireHashP h_wire;
+ bool has_no_policy;
+
+ /**
+ * Additional details for policy extension relevant for this
+ * deposit operation, possibly NULL!
+ */
+ json_t *policy_json;
/**
* If @e policy_json was present, the corresponding policy extension
@@ -84,6 +92,11 @@ struct BatchDepositContext
struct TALER_ExtensionPolicyHashP h_policy;
/**
+ * Hash over the merchant's payto://-URI with the wire salt.
+ */
+ struct TALER_MerchantWireHashP h_wire;
+
+ /**
* When @e policy_details are persisted, this contains the id of the record
* in the policy_details table.
*/
@@ -121,11 +134,11 @@ reply_batch_deposit_success (
&TEH_keys_exchange_sign_,
&bd->h_contract_terms,
&dc->h_wire,
- NULL != dc->policy_json ? &dc->h_policy : NULL,
+ dc->has_no_policy ? NULL : &dc->h_policy,
dc->exchange_timestamp,
bd->wire_deadline,
bd->refund_deadline,
- &dc->policy_details.accumulated_total, /* excludes fees */
+ &dc->accumulated_total_without_fee,
bd->num_cdis,
csigs,
&dc->bd.merchant_pub,
@@ -176,13 +189,13 @@ batch_deposit_transaction (void *cls,
/* If the deposit has a policy associated to it, persist it. This will
* insert or update the record. */
- if (NULL != dc->policy_json)
+ if (! dc->has_no_policy)
{
qs = TEH_plugin->persist_policy_details (
TEH_plugin->cls,
&dc->policy_details,
&dc->bd.policy_details_serial_id,
- &dc->policy_details.accumulated_total,
+ &dc->accumulated_total_without_fee,
&dc->policy_details.fulfillment_state);
if (qs < 0)
return qs;
@@ -237,13 +250,13 @@ batch_deposit_transaction (void *cls,
in_conflict ? "in conflict" : "no conflict");
if (in_conflict)
{
- /* FIXME: #7267 conflicting contract != insufficient funds */
+ /* FIXME: #8002 conflicting contract != insufficient funds */
*mhd_ret
= TEH_RESPONSE_reply_coin_insufficient_funds (
connection,
TALER_EC_EXCHANGE_DEPOSIT_CONFLICTING_CONTRACT,
- &bd->cdis[0 /* SEE FIXME-#7267 Oec above! */].coin.denom_pub_hash,
- &bd->cdis[0 /* SEE FIXME-#7267 Oec above! */].coin.coin_pub);
+ &bd->cdis[0 /* SEE FIXME-#8002 Oec above! */].coin.denom_pub_hash,
+ &bd->cdis[0 /* SEE FIXME-#8002 Oec above! */].coin.coin_pub);
return GNUNET_DB_STATUS_HARD_ERROR;
}
if (! balance_ok)
@@ -495,7 +508,7 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc,
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_json ("policy",
&dc.policy_json),
- NULL),
+ &dc.has_no_policy),
GNUNET_JSON_spec_timestamp ("timestamp",
&bd->wallet_timestamp),
GNUNET_JSON_spec_mark_optional (
@@ -571,8 +584,12 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc,
&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 (NULL != dc.policy_json)
+ if (! dc.has_no_policy)
{
const char *error_hint = NULL;
@@ -641,10 +658,11 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc,
&amount_without_fee,
&cdis[i].amount_with_fee,
&deposit_fees[i]));
+
GNUNET_assert (0 <=
TALER_amount_add (
- &dc.policy_details.accumulated_total,
- &dc.policy_details.accumulated_total,
+ &dc.accumulated_total_without_fee,
+ &dc.accumulated_total_without_fee,
&amount_without_fee));
}
if (GNUNET_OK != res)
diff --git a/src/exchange/taler-exchange-httpd_db.c b/src/exchange/taler-exchange-httpd_db.c
index 5660074ee..a00a97856 100644
--- a/src/exchange/taler-exchange-httpd_db.c
+++ b/src/exchange/taler-exchange-httpd_db.c
@@ -37,14 +37,14 @@ TEH_make_coin_known (const struct TALER_CoinPublicInfo *coin,
{
enum TALER_EXCHANGEDB_CoinKnownStatus cks;
struct TALER_DenominationHashP h_denom_pub;
- struct TALER_AgeCommitmentHash age_hash;
+ struct TALER_AgeCommitmentHash h_age_commitment;
/* make sure coin is 'known' in database */
cks = TEH_plugin->ensure_coin_known (TEH_plugin->cls,
coin,
known_coin_id,
&h_denom_pub,
- &age_hash);
+ &h_age_commitment);
switch (cks)
{
case TALER_EXCHANGEDB_CKS_ADDED:
@@ -70,13 +70,12 @@ TEH_make_coin_known (const struct TALER_CoinPublicInfo *coin,
&coin->coin_pub);
return GNUNET_DB_STATUS_HARD_ERROR;
case TALER_EXCHANGEDB_CKS_AGE_CONFLICT:
- /* FIXME: insufficient_funds != Age conflict! See issue #7267, need new
- * strategy for evidence gathering */
- *mhd_ret = TEH_RESPONSE_reply_coin_insufficient_funds (
+ *mhd_ret = TEH_RESPONSE_reply_coin_age_commitment_conflict (
connection,
TALER_EC_EXCHANGE_GENERIC_COIN_CONFLICTING_AGE_HASH,
&h_denom_pub,
- &coin->coin_pub);
+ &coin->coin_pub,
+ &h_age_commitment);
return GNUNET_DB_STATUS_HARD_ERROR;
}
GNUNET_assert (0);
diff --git a/src/exchange/taler-exchange-httpd_extensions.c b/src/exchange/taler-exchange-httpd_extensions.c
index dd0fada76..d62a618ae 100644
--- a/src/exchange/taler-exchange-httpd_extensions.c
+++ b/src/exchange/taler-exchange-httpd_extensions.c
@@ -23,6 +23,7 @@
#include "taler-exchange-httpd_keys.h"
#include "taler-exchange-httpd_responses.h"
#include "taler-exchange-httpd_extensions.h"
+#include "taler_extensions_policy.h"
#include "taler_json_lib.h"
#include "taler_mhd_lib.h"
#include "taler_extensions.h"
@@ -256,11 +257,16 @@ policy_fulfillment_transaction (
{
struct TALER_PolicyFulfillmentTransactionData *fulfillment = cls;
+ /* FIXME[oec]: use connection and mhd_ret? */
+ (void) connection;
+ (void) mhd_ret;
+
return TEH_plugin->add_policy_fulfillment_proof (TEH_plugin->cls,
fulfillment);
}
+/* FIXME[oec]-#7999: In this handler: do we transition correctly between states? */
MHD_RESULT
TEH_extensions_post_handler (
struct TEH_RequestContext *rc,
@@ -338,14 +344,48 @@ TEH_extensions_post_handler (
qs = TEH_plugin->get_policy_details (TEH_plugin->cls,
&hcs[idx],
&policy_details[idx]);
- if (qs < 0)
+ if (0 > qs)
+ {
+ GNUNET_free (hcs);
+ GNUNET_free (policy_details);
+ return TALER_MHD_reply_with_error (rc->connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_EXCHANGE_GENERIC_OPERATION_UNKNOWN,
+ "a policy_hash_code couldn't be found");
+ }
+
+ /* We proceed according to the state of fulfillment */
+ switch (policy_details[idx].fulfillment_state)
{
- error_msg = "a policy_hash_code couldn't be found";
+ case TALER_PolicyFulfillmentReady:
+ break;
+ case TALER_PolicyFulfillmentInsufficient:
+ error_msg = "a policy is not yet fully funded";
+ ret = GNUNET_SYSERR;
+ break;
+ case TALER_PolicyFulfillmentTimeout:
+ error_msg = "a policy is has already timed out";
+ ret = GNUNET_SYSERR;
break;
+ case TALER_PolicyFulfillmentSuccess:
+ /* FIXME[oec]-#8001: Idempotency handling. */
+ GNUNET_break (0);
+ break;
+ case TALER_PolicyFulfillmentFailure:
+ /* FIXME[oec]-#7999: What to do in the failure case? */
+ GNUNET_break (0);
+ break;
+ default:
+ /* Unknown state */
+ GNUNET_assert (0);
}
+
+ if (GNUNET_OK != ret)
+ break;
}
GNUNET_free (hcs);
+
if (GNUNET_OK != ret)
{
GNUNET_free (policy_details);
diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c
index 322da3877..c1aa9db6f 100644
--- a/src/exchange/taler-exchange-httpd_responses.c
+++ b/src/exchange/taler-exchange-httpd_responses.c
@@ -178,6 +178,28 @@ TEH_RESPONSE_reply_coin_insufficient_funds (
MHD_RESULT
+TEH_RESPONSE_reply_coin_age_commitment_conflict (
+ struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_AgeCommitmentHash *h_age_commitment_hash)
+{
+ return TALER_MHD_REPLY_JSON_PACK (
+ connection,
+ TALER_ErrorCode_get_http_status_safe (ec),
+ TALER_JSON_pack_ec (ec),
+ GNUNET_JSON_pack_data_auto ("coin_pub",
+ coin_pub),
+ GNUNET_JSON_pack_data_auto ("h_denom_pub",
+ h_denom_pub),
+ GNUNET_JSON_pack_data_auto ("h_age_commitment_hash",
+ h_age_commitment_hash)
+ );
+}
+
+
+MHD_RESULT
TEH_RESPONSE_reply_reserve_insufficient_balance (
struct MHD_Connection *connection,
enum TALER_ErrorCode ec,
diff --git a/src/exchange/taler-exchange-httpd_responses.h b/src/exchange/taler-exchange-httpd_responses.h
index 8adf1136b..5fe106e17 100644
--- a/src/exchange/taler-exchange-httpd_responses.h
+++ b/src/exchange/taler-exchange-httpd_responses.h
@@ -160,6 +160,27 @@ TEH_RESPONSE_reply_coin_insufficient_funds (
const struct TALER_CoinSpendPublicKeyP *coin_pub);
/**
+ * Send proof that a request is invalid to client because of
+ * a conflicting value for the age commitment hash of a coin.
+ * This function will create a message with the conflicting
+ * hash value for the age commitment of the given coin.
+ *
+ * @param connection connection to the client
+ * @param ec error code to return
+ * @param h_denom_pub hash of the denomination of the coin
+ * @param coin_pub public key of the coin
+ * @param h_age_commitment hash of the age commitment as found in the database
+ * @return MHD result code
+ */
+MHD_RESULT
+TEH_RESPONSE_reply_coin_age_commitment_conflict (
+ struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_AgeCommitmentHash *h_age_commitment);
+
+/**
* Fundamental details about a purse.
*/
struct TEH_PurseDetails
diff --git a/src/exchangedb/exchange_do_deposit.sql b/src/exchangedb/exchange_do_deposit.sql
index 1156c7de5..7116117ff 100644
--- a/src/exchangedb/exchange_do_deposit.sql
+++ b/src/exchangedb/exchange_do_deposit.sql
@@ -142,6 +142,7 @@ THEN
IF NOT FOUND
THEN
-- Deposit exists, but with *strange* differences. Not allowed.
+ -- FIXME #8002: Surely we need to provide the client more data in this case.
out_conflict=TRUE;
RETURN;
END IF;
diff --git a/src/exchangedb/exchange_do_insert_or_update_policy_details.sql b/src/exchangedb/exchange_do_insert_or_update_policy_details.sql
index 53cd2989e..85e52d3d3 100644
--- a/src/exchangedb/exchange_do_insert_or_update_policy_details.sql
+++ b/src/exchangedb/exchange_do_insert_or_update_policy_details.sql
@@ -93,14 +93,14 @@ BEGIN
-- Set the fulfillment_state according to the values.
-- For now, we only update the state when it was INSUFFICIENT.
- -- FIXME: What to do in case of Failure or other state?
- IF (out_fullfillment_state = 1) -- INSUFFICIENT
+ -- FIXME[oec] #7999: What to do in case of Failure or other state?
+ IF (out_fullfillment_state = 2) -- INSUFFICIENT
THEN
IF (out_accumulated_total.val >= cur_commitment.val OR
(out_accumulated_total.val = cur_commitment.val AND
out_accumulated_total.frac >= cur_commitment.frac))
THEN
- out_fulfillment_state = 2; -- READY
+ out_fulfillment_state = 3; -- READY
END IF;
END IF;
diff --git a/src/exchangedb/pg_add_policy_fulfillment_proof.c b/src/exchangedb/pg_add_policy_fulfillment_proof.c
index 0fd6b1c92..93d070712 100644
--- a/src/exchangedb/pg_add_policy_fulfillment_proof.c
+++ b/src/exchangedb/pg_add_policy_fulfillment_proof.c
@@ -55,6 +55,7 @@ TEH_PG_add_policy_fulfillment_proof (
enum GNUNET_DB_QueryStatus qs;
struct PostgresClosure *pg = cls;
size_t count = fulfillment->details_count;
+ /* FIXME: this seems to be prone to VLA attacks */
struct GNUNET_HashCode hcs[count];
/* Create the sorted policy_hash_codes */
@@ -84,8 +85,7 @@ TEH_PG_add_policy_fulfillment_proof (
GNUNET_PQ_query_param_timestamp (&fulfillment->timestamp),
TALER_PQ_query_param_json (fulfillment->proof),
GNUNET_PQ_query_param_auto_from_type (&fulfillment->h_proof),
- GNUNET_PQ_query_param_fixed_size (hcs,
- count * sizeof(struct GNUNET_HashCode)),
+ TALER_PQ_query_param_array_hash_code (count, hcs, pg->conn),
GNUNET_PQ_query_param_end
};
struct GNUNET_PQ_ResultSpec rs[] = {
@@ -132,7 +132,6 @@ TEH_PG_add_policy_fulfillment_proof (
GNUNET_PQ_query_param_end
};
- // FIXME-Oec: review if this is the intended logic here!
PREPARE (pg,
"update_policy_details",
"UPDATE policy_details SET"
@@ -151,5 +150,10 @@ TEH_PG_add_policy_fulfillment_proof (
}
}
+ /*
+ * FIXME[oec]-#7999: When all policies of a deposit are fulfilled,
+ * unblock it and trigger a wire-transfer.
+ */
+
return qs;
}
diff --git a/src/exchangedb/pg_do_deposit.c b/src/exchangedb/pg_do_deposit.c
index 0ba45b628..64e7886a7 100644
--- a/src/exchangedb/pg_do_deposit.c
+++ b/src/exchangedb/pg_do_deposit.c
@@ -83,6 +83,7 @@ TEH_PG_do_deposit (
GNUNET_PQ_result_spec_uint32 ("insufficient_balance_coin_index",
bad_balance_index),
balance_ok),
+ /* FIXME #8002: We need more data to communicate the conflict to the client */
GNUNET_PQ_result_spec_bool ("conflicted",
ctr_conflict),
GNUNET_PQ_result_spec_end
diff --git a/src/include/taler_extensions_policy.h b/src/include/taler_extensions_policy.h
index 7750f58f1..b10c0d8a2 100644
--- a/src/include/taler_extensions_policy.h
+++ b/src/include/taler_extensions_policy.h
@@ -28,6 +28,8 @@
/*
* @brief Describes the states of fulfillment of a policy bound to a deposit
+ * NOTE: These values must be in sync with their use in stored procedures, f.e.
+ * exchange_do_insert_or_update_policy_details.
*/
enum TALER_PolicyFulfillmentState
{
diff --git a/src/kyclogic/Makefile.am b/src/kyclogic/Makefile.am
index d43d4a6c1..fae865bad 100644
--- a/src/kyclogic/Makefile.am
+++ b/src/kyclogic/Makefile.am
@@ -78,6 +78,7 @@ libtaler_plugin_kyclogic_template_la_LIBADD = \
$(LTLIBINTL)
libtaler_plugin_kyclogic_template_la_LDFLAGS = \
$(TALER_PLUGIN_LDFLAGS) \
+ -lgnunetcurl \
-lgnunetutil \
$(XLIB)
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 230dfba21..1291fd3a4 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -87,6 +87,7 @@ libtalerexchange_la_LIBADD = \
-lgnunetjson \
-lgnunetutil \
-ljansson \
+ -lm \
$(LIBGNURLCURL_LIBS) \
$(XLIB)
diff --git a/src/testing/taler-unified-setup.sh b/src/testing/taler-unified-setup.sh
index 479a125fa..958421666 100755
--- a/src/testing/taler-unified-setup.sh
+++ b/src/testing/taler-unified-setup.sh
@@ -329,6 +329,12 @@ then
-c "$CONF" \
"$AUSER" "$APASS" \
&> libeufin-bank-passwd.log
+ libeufin-bank \
+ edit-account \
+ -c "$CONF" \
+ --debit_threshold="$CURRENCY:1000000" \
+ "$AUSER" \
+ &> libeufin-bank-debit-threshold.log
echo " OK"
fi
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index 4ebd6397c..2a0304e03 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -115,6 +115,7 @@ libtalerutil_la_LIBADD = \
-ljansson \
$(LIBGCRYPT_LIBS) \
-lmicrohttpd $(XLIB) \
+ -lunistring \
-lz \
-lm
diff --git a/src/util/exchange_signatures.c b/src/util/exchange_signatures.c
index bc5fe439f..aaefb5cec 100644
--- a/src/util/exchange_signatures.c
+++ b/src/util/exchange_signatures.c
@@ -120,7 +120,8 @@ TALER_exchange_online_deposit_confirmation_sign (
.exchange_timestamp = GNUNET_TIME_timestamp_hton (exchange_timestamp),
.wire_deadline = GNUNET_TIME_timestamp_hton (wire_deadline),
.refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline),
- .merchant_pub = *merchant_pub
+ .merchant_pub = *merchant_pub,
+ .h_policy = {{{0}}}
};
struct GNUNET_HashContext *hc;