From 282e4f59ee849c6c84f753e8fae5691aaf8e9303 Mon Sep 17 00:00:00 2001
From: Christian Grothoff
Date: Sun, 26 Jan 2020 17:48:13 +0100
Subject: address bank_api_credit comment/FIXME from Florian, also adapt debit
logic accordingly
---
src/bank-lib/bank_api_credit.c | 23 +++++++----------------
src/bank-lib/bank_api_debit.c | 30 ++++++++++++++----------------
2 files changed, 21 insertions(+), 32 deletions(-)
diff --git a/src/bank-lib/bank_api_credit.c b/src/bank-lib/bank_api_credit.c
index 50725a4e..66e128da 100644
--- a/src/bank-lib/bank_api_credit.c
+++ b/src/bank-lib/bank_api_credit.c
@@ -30,7 +30,7 @@
/**
- * @brief A /history Handle
+ * @brief A /history/incoming Handle
*/
struct TALER_BANK_CreditHistoryHandle
{
@@ -173,30 +173,21 @@ handle_credit_history_finished (void *cls,
GNUNET_break_op (0);
ec = TALER_JSON_get_error_code (j);
break;
- case MHD_HTTP_FORBIDDEN:
- /* Access denied */
- GNUNET_break_op (0);
- ec = TALER_JSON_get_error_code (j);
- break;
case MHD_HTTP_UNAUTHORIZED:
- /* FIXME(dold): I don't get this comment below. What signatures would the
- bank even verify?! */
- /* Nothing really to verify, bank says one of the signatures is
- invalid; as we checked them, this should never happen, we
- should pass the JSON reply to the application */
- GNUNET_break_op (0);
+ /* Nothing really to verify, bank says the HTTP Authentication
+ failed. May happen if HTTP authentication is used and the
+ user supplied a wrong username/password combination. */
ec = TALER_JSON_get_error_code (j);
break;
case MHD_HTTP_NOT_FOUND:
- /* Nothing really to verify, this should never
- happen, we should pass the JSON reply to the application */
- GNUNET_break_op (0);
+ /* Nothing really to verify: the bank is either unaware
+ of the endpoint (not a bank), or of the account.
+ We should pass the JSON (?) reply to the application */
ec = TALER_JSON_get_error_code (j);
break;
case MHD_HTTP_INTERNAL_SERVER_ERROR:
/* Server had an internal issue; we should retry, but this API
leaves this to the application */
- GNUNET_break_op (0);
ec = TALER_JSON_get_error_code (j);
break;
default:
diff --git a/src/bank-lib/bank_api_debit.c b/src/bank-lib/bank_api_debit.c
index 0e218eb4..58f6ae6d 100644
--- a/src/bank-lib/bank_api_debit.c
+++ b/src/bank-lib/bank_api_debit.c
@@ -30,7 +30,7 @@
/**
- * @brief A /history Handle
+ * @brief A /history/outgoing Handle
*/
struct TALER_BANK_DebitHistoryHandle
{
@@ -129,16 +129,16 @@ parse_account_history (struct TALER_BANK_DebitHistoryHandle *hh,
/**
* Function called when we're done processing the
- * HTTP /history request.
+ * HTTP /history/outgoing request.
*
* @param cls the `struct TALER_BANK_DebitHistoryHandle`
* @param response_code HTTP response code, 0 on error
* @param response parsed JSON result, NULL on error
*/
static void
-handle_history_finished (void *cls,
- long response_code,
- const void *response)
+handle_debit_history_finished (void *cls,
+ long response_code,
+ const void *response)
{
struct TALER_BANK_DebitHistoryHandle *hh = cls;
enum TALER_ErrorCode ec;
@@ -169,21 +169,19 @@ handle_history_finished (void *cls,
case MHD_HTTP_BAD_REQUEST:
/* This should never happen, either us or the bank is buggy
(or API version conflict); just pass JSON reply to the application */
- ec = TALER_JSON_get_error_code (j);
- break;
- case MHD_HTTP_FORBIDDEN:
- /* Access denied */
+ GNUNET_break_op (0);
ec = TALER_JSON_get_error_code (j);
break;
case MHD_HTTP_UNAUTHORIZED:
- /* Nothing really to verify, bank says one of the signatures is
- invalid; as we checked them, this should never happen, we
- should pass the JSON reply to the application */
+ /* Nothing really to verify, bank says the HTTP Authentication
+ failed. May happen if HTTP authentication is used and the
+ user supplied a wrong username/password combination. */
ec = TALER_JSON_get_error_code (j);
break;
case MHD_HTTP_NOT_FOUND:
- /* Nothing really to verify, this should never
- happen, we should pass the JSON reply to the application */
+ /* Nothing really to verify: the bank is either unaware
+ of the endpoint (not a bank), or of the account.
+ We should pass the JSON (?) reply to the application */
ec = TALER_JSON_get_error_code (j);
break;
case MHD_HTTP_INTERNAL_SERVER_ERROR:
@@ -196,7 +194,7 @@ handle_history_finished (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unexpected response code %u\n",
(unsigned int) response_code);
- GNUNET_break (0);
+ GNUNET_break_op (0);
ec = TALER_JSON_get_error_code (j);
response_code = 0;
break;
@@ -292,7 +290,7 @@ TALER_BANK_debit_history (struct GNUNET_CURL_Context *ctx,
hh->job = GNUNET_CURL_job_add2 (ctx,
eh,
NULL,
- &handle_history_finished,
+ &handle_debit_history_finished,
hh);
return hh;
}
--
cgit v1.2.3
From f4f86d2b0149231e95b81f12a607c670ad74f02f Mon Sep 17 00:00:00 2001
From: Christian Grothoff
Date: Sun, 26 Jan 2020 18:51:25 +0100
Subject: increse log level on errors
---
src/exchange/taler-exchange-wirewatch.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/exchange/taler-exchange-wirewatch.c b/src/exchange/taler-exchange-wirewatch.c
index 21d96668..972cee34 100644
--- a/src/exchange/taler-exchange-wirewatch.c
+++ b/src/exchange/taler-exchange-wirewatch.c
@@ -340,7 +340,7 @@ history_cb (void *cls,
hh = NULL;
if (TALER_EC_NONE != ec)
{
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Error fetching history: ec=%u, http_status=%u\n",
(unsigned int) ec,
http_status);
--
cgit v1.2.3
From 232606fb57e3c74b62aa78d49225e2bb3c0c9ab4 Mon Sep 17 00:00:00 2001
From: Christian Grothoff
Date: Mon, 3 Feb 2020 23:42:47 +0100
Subject: add IF NOT EXISTS for indices
---
src/auditordb/0001.sql | 4 +--
src/exchange/taler-exchange-aggregator.c | 8 ++---
src/exchangedb/0001.sql | 54 ++++++++++++++++----------------
src/json/json.c | 3 +-
4 files changed, 35 insertions(+), 34 deletions(-)
diff --git a/src/auditordb/0001.sql b/src/auditordb/0001.sql
index 7f47f035..3e666519 100644
--- a/src/auditordb/0001.sql
+++ b/src/auditordb/0001.sql
@@ -115,7 +115,7 @@ CREATE TABLE IF NOT EXISTS auditor_reserves
,auditor_reserves_rowid BIGSERIAL UNIQUE
,origin_account TEXT
);
-CREATE INDEX auditor_reserves_by_reserve_pub
+CREATE INDEX IF NOT EXISTS auditor_reserves_by_reserve_pub
ON auditor_reserves
(reserve_pub);
-- Table with the sum of the balances of all customer reserves
@@ -203,7 +203,7 @@ CREATE TABLE IF NOT EXISTS auditor_historic_reserve_summary
,reserve_profits_val INT8 NOT NULL
,reserve_profits_frac INT4 NOT NULL
);
-CREATE INDEX auditor_historic_reserve_summary_by_master_pub_start_date
+CREATE INDEX IF NOT EXISTS auditor_historic_reserve_summary_by_master_pub_start_date
ON auditor_historic_reserve_summary
(master_pub
,start_date);
diff --git a/src/exchange/taler-exchange-aggregator.c b/src/exchange/taler-exchange-aggregator.c
index a43277b2..5f57c829 100644
--- a/src/exchange/taler-exchange-aggregator.c
+++ b/src/exchange/taler-exchange-aggregator.c
@@ -582,6 +582,7 @@ shutdown_task (void *cls)
ctc = NULL;
}
TALER_EXCHANGEDB_plugin_unload (db_plugin);
+ db_plugin = NULL;
{
struct WireAccount *wa;
@@ -670,6 +671,7 @@ parse_wirewatch_config ()
fprintf (stderr,
"Failed to initialize DB tables\n");
TALER_EXCHANGEDB_plugin_unload (db_plugin);
+ db_plugin = NULL;
return GNUNET_SYSERR;
}
TALER_EXCHANGEDB_find_accounts (cfg,
@@ -680,6 +682,7 @@ parse_wirewatch_config ()
fprintf (stderr,
"No wire accounts configured for debit!\n");
TALER_EXCHANGEDB_plugin_unload (db_plugin);
+ db_plugin = NULL;
return GNUNET_SYSERR;
}
return GNUNET_OK;
@@ -1179,10 +1182,7 @@ expired_reserve_cb (void *cls,
/* Reserve balance was almost zero OR soft error */
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Reserve was virtually empty, moving on\n");
- (void) commit_or_warn (ctc->session);
- GNUNET_free (ctc->method);
- GNUNET_free (ctc);
- ctc = NULL;
+ (void) commit_or_warn (session);
task = GNUNET_SCHEDULER_add_now (&run_transfers,
NULL);
return qs;
diff --git a/src/exchangedb/0001.sql b/src/exchangedb/0001.sql
index 8e7ea0bf..02dc68cf 100644
--- a/src/exchangedb/0001.sql
+++ b/src/exchangedb/0001.sql
@@ -42,7 +42,7 @@ CREATE TABLE IF NOT EXISTS denominations
,fee_refund_val INT8 NOT NULL
,fee_refund_frac INT4 NOT NULL
);
-CREATE INDEX denominations_expire_legal_index
+CREATE INDEX IF NOT EXISTS denominations_expire_legal_index
ON denominations
(expire_legal);
@@ -65,18 +65,18 @@ CREATE TABLE IF NOT EXISTS reserves
,gc_date INT8 NOT NULL
);
-- index on reserves table (TODO: useless due to primary key!?)
-CREATE INDEX reserves_reserve_pub_index
+CREATE INDEX IF NOT EXISTS reserves_reserve_pub_index
ON reserves
(reserve_pub);
-- index for get_expired_reserves
-CREATE INDEX reserves_expiration_index
+CREATE INDEX IF NOT EXISTS reserves_expiration_index
ON reserves
(expiration_date
,current_balance_val
,current_balance_frac
);
-- index for reserve GC operations
-CREATE INDEX reserves_gc_index
+CREATE INDEX IF NOT EXISTS reserves_gc_index
ON reserves
(gc_date);
-- reserves_in table collects the transactions which transfer funds
@@ -94,12 +94,12 @@ CREATE TABLE IF NOT EXISTS reserves_in
,PRIMARY KEY (reserve_pub, wire_reference)
);
-- Create indices on reserves_in
-CREATE INDEX reserves_in_execution_index
+CREATE INDEX IF NOT EXISTS reserves_in_execution_index
ON reserves_in
(exchange_account_section
,execution_date
);
-CREATE INDEX reserves_in_exchange_account_serial
+CREATE INDEX IF NOT EXISTS reserves_in_exchange_account_serial
ON reserves_in
(exchange_account_section,
reserve_in_serial_id DESC
@@ -116,7 +116,7 @@ CREATE TABLE IF NOT EXISTS reserves_close
,amount_frac INT4 NOT NULL
,closing_fee_val INT8 NOT NULL
,closing_fee_frac INT4 NOT NULL);
-CREATE INDEX reserves_close_by_reserve
+CREATE INDEX IF NOT EXISTS reserves_close_by_reserve
ON reserves_close
(reserve_pub);
-- Table with the withdraw operations that have been performed on a reserve.
@@ -137,13 +137,13 @@ CREATE TABLE IF NOT EXISTS reserves_out
,amount_with_fee_frac INT4 NOT NULL
);
-- Index blindcoins(reserve_pub) for get_reserves_out statement
-CREATE INDEX reserves_out_reserve_pub_index
+CREATE INDEX IF NOT EXISTS reserves_out_reserve_pub_index
ON reserves_out
(reserve_pub);
-CREATE INDEX reserves_out_execution_date
+CREATE INDEX IF NOT EXISTS reserves_out_execution_date
ON reserves_out
(execution_date);
-CREATE INDEX reserves_out_for_get_withdraw_info
+CREATE INDEX IF NOT EXISTS reserves_out_for_get_withdraw_info
ON reserves_out
(denom_pub_hash
,h_blind_ev
@@ -155,7 +155,7 @@ CREATE TABLE IF NOT EXISTS known_coins
,denom_pub_hash BYTEA NOT NULL REFERENCES denominations (denom_pub_hash) ON DELETE CASCADE
,denom_sig BYTEA NOT NULL
);
-CREATE INDEX known_coins_by_denomination
+CREATE INDEX IF NOT EXISTS known_coins_by_denomination
ON known_coins
(denom_pub_hash);
-- Table with the commitments made when melting a coin. */
@@ -168,7 +168,7 @@ CREATE TABLE IF NOT EXISTS refresh_commitments
,amount_with_fee_frac INT4 NOT NULL
,noreveal_index INT4 NOT NULL
);
-CREATE INDEX refresh_commitments_old_coin_pub_index
+CREATE INDEX IF NOT EXISTS refresh_commitments_old_coin_pub_index
ON refresh_commitments
(old_coin_pub);
-- Table with the revelations about the new coins that are to be created
@@ -188,7 +188,7 @@ CREATE TABLE IF NOT EXISTS refresh_revealed_coins
,PRIMARY KEY (rc, newcoin_index)
,UNIQUE (h_coin_ev)
);
-CREATE INDEX refresh_revealed_coins_coin_pub_index
+CREATE INDEX IF NOT EXISTS refresh_revealed_coins_coin_pub_index
ON refresh_revealed_coins
(denom_pub_hash);
-- Table with the transfer keys of a refresh operation; includes
@@ -203,7 +203,7 @@ CREATE TABLE IF NOT EXISTS refresh_transfer_keys
-- for get_link (not sure if this helps, as there should be very few
-- transfer_pubs per rc, but at least in theory this helps the ORDER BY
-- clause.
-CREATE INDEX refresh_transfer_keys_coin_tpub
+CREATE INDEX IF NOT EXISTS refresh_transfer_keys_coin_tpub
ON refresh_transfer_keys
(rc
,transfer_pub
@@ -228,14 +228,14 @@ CREATE TABLE IF NOT EXISTS deposits
,UNIQUE (coin_pub, merchant_pub, h_contract_terms)
);
-- Index for get_deposit_for_wtid and get_deposit_statement */
-CREATE INDEX deposits_coin_pub_merchant_contract_index
+CREATE INDEX IF NOT EXISTS deposits_coin_pub_merchant_contract_index
ON deposits
(coin_pub
,merchant_pub
,h_contract_terms
);
-- Index for deposits_get_ready
-CREATE INDEX deposits_get_ready_index
+CREATE INDEX IF NOT EXISTS deposits_get_ready_index
ON deposits
(tiny
,done
@@ -243,7 +243,7 @@ CREATE INDEX deposits_get_ready_index
,refund_deadline
);
-- Index for deposits_iterate_matching
-CREATE INDEX deposits_iterate_matching
+CREATE INDEX IF NOT EXISTS deposits_iterate_matching
ON deposits
(merchant_pub
,h_wire
@@ -265,7 +265,7 @@ CREATE TABLE IF NOT EXISTS refunds
,amount_with_fee_frac INT4 NOT NULL
,PRIMARY KEY (coin_pub, merchant_pub, h_contract_terms, rtransaction_id)
);
-CREATE INDEX refunds_coin_pub_index
+CREATE INDEX IF NOT EXISTS refunds_coin_pub_index
ON refunds
(coin_pub);
-- This table contains the data for
@@ -287,7 +287,7 @@ CREATE TABLE IF NOT EXISTS aggregation_tracking
,wtid_raw BYTEA CONSTRAINT wire_out_ref REFERENCES wire_out(wtid_raw) ON DELETE CASCADE DEFERRABLE
);
-- Index for lookup_transactions statement on wtid
-CREATE INDEX aggregation_tracking_wtid_index
+CREATE INDEX IF NOT EXISTS aggregation_tracking_wtid_index
ON aggregation_tracking
(wtid_raw);
-- Table for the wire fees.
@@ -302,7 +302,7 @@ CREATE TABLE IF NOT EXISTS wire_fee
,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)
,PRIMARY KEY (wire_method, start_date)
);
-CREATE INDEX wire_fee_gc_index
+CREATE INDEX IF NOT EXISTS wire_fee_gc_index
ON wire_fee
(end_date);
-- Table for /recoup information
@@ -317,13 +317,13 @@ CREATE TABLE IF NOT EXISTS recoup
,timestamp INT8 NOT NULL
,h_blind_ev BYTEA NOT NULL REFERENCES reserves_out (h_blind_ev) ON DELETE CASCADE
);
-CREATE INDEX recoup_by_coin_index
+CREATE INDEX IF NOT EXISTS recoup_by_coin_index
ON recoup
(coin_pub);
-CREATE INDEX recoup_by_h_blind_ev
+CREATE INDEX IF NOT EXISTS recoup_by_h_blind_ev
ON recoup
(h_blind_ev);
-CREATE INDEX recoup_for_by_reserve
+CREATE INDEX IF NOT EXISTS recoup_for_by_reserve
ON recoup
(coin_pub
,h_blind_ev
@@ -340,13 +340,13 @@ CREATE TABLE IF NOT EXISTS recoup_refresh
,timestamp INT8 NOT NULL
,h_blind_ev BYTEA NOT NULL REFERENCES refresh_revealed_coins (h_coin_ev) ON DELETE CASCADE
);
-CREATE INDEX recoup_refresh_by_coin_index
+CREATE INDEX IF NOT EXISTS recoup_refresh_by_coin_index
ON recoup_refresh
(coin_pub);
-CREATE INDEX recoup_refresh_by_h_blind_ev
+CREATE INDEX IF NOT EXISTS recoup_refresh_by_h_blind_ev
ON recoup_refresh
(h_blind_ev);
-CREATE INDEX recoup_refresh_for_by_reserve
+CREATE INDEX IF NOT EXISTS recoup_refresh_for_by_reserve
ON recoup_refresh
(coin_pub
,h_blind_ev
@@ -360,7 +360,7 @@ CREATE TABLE IF NOT EXISTS prewire
,buf BYTEA NOT NULL
);
-- Index for wire_prepare_data_get and gc_prewire statement
-CREATE INDEX prepare_iteration_index
+CREATE INDEX IF NOT EXISTS prepare_iteration_index
ON prewire
(finished);
diff --git a/src/json/json.c b/src/json/json.c
index 6de29931..f0c0aff5 100644
--- a/src/json/json.c
+++ b/src/json/json.c
@@ -81,7 +81,8 @@ TALER_JSON_get_error_code (const json_t *json)
so we are dealing with a missing error code here. */
if (NULL == jc)
{
- GNUNET_break_op (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Expected Taler error code `code' in JSON, but field does not exist!\n");
return TALER_EC_INVALID;
}
if (json_is_integer (jc))
--
cgit v1.2.3
From d47241e0e12ace8530ef4ecb2f9ac0f0918dcff6 Mon Sep 17 00:00:00 2001
From: Christian Grothoff
Date: Tue, 4 Feb 2020 00:04:29 +0100
Subject: fix double continuation scheduling
---
src/exchange/taler-exchange-aggregator.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/src/exchange/taler-exchange-aggregator.c b/src/exchange/taler-exchange-aggregator.c
index 5f57c829..a03eaff5 100644
--- a/src/exchange/taler-exchange-aggregator.c
+++ b/src/exchange/taler-exchange-aggregator.c
@@ -1183,6 +1183,8 @@ expired_reserve_cb (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Reserve was virtually empty, moving on\n");
(void) commit_or_warn (session);
+ erc->async_cont = GNUNET_YES;
+ GNUNET_assert (NULL == task);
task = GNUNET_SCHEDULER_add_now (&run_transfers,
NULL);
return qs;
@@ -1223,6 +1225,7 @@ expired_reserve_cb (void *cls,
return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
}
erc->async_cont = GNUNET_YES;
+ GNUNET_assert (NULL == task);
task = GNUNET_SCHEDULER_add_now (&run_transfers,
NULL);
GNUNET_free (ctc->method);
@@ -1299,6 +1302,7 @@ run_reserve_closures (void *cls)
case GNUNET_DB_STATUS_SOFT_ERROR:
db_plugin->rollback (db_plugin->cls,
session);
+ GNUNET_assert (NULL == task);
task = GNUNET_SCHEDULER_add_now (&run_reserve_closures,
NULL);
return;
@@ -1308,6 +1312,7 @@ run_reserve_closures (void *cls)
reserves_idle = GNUNET_YES;
db_plugin->rollback (db_plugin->cls,
session);
+ GNUNET_assert (NULL == task);
task = GNUNET_SCHEDULER_add_now (&run_aggregation,
NULL);
return;
@@ -1315,6 +1320,7 @@ run_reserve_closures (void *cls)
(void) commit_or_warn (session);
if (GNUNET_YES == erc.async_cont)
break;
+ GNUNET_assert (NULL == task);
task = GNUNET_SCHEDULER_add_now (&run_reserve_closures,
NULL);
return;
@@ -1345,6 +1351,7 @@ run_aggregation (void *cls)
return;
if (0 == (++swap % 2))
{
+ GNUNET_assert (NULL == task);
task = GNUNET_SCHEDULER_add_now (&run_reserve_closures,
NULL);
return;
@@ -1392,6 +1399,7 @@ run_aggregation (void *cls)
{
/* should re-try immediately */
swap--; /* do not count failed attempts */
+ GNUNET_assert (NULL == task);
task = GNUNET_SCHEDULER_add_now (&run_aggregation,
NULL);
return;
@@ -1408,15 +1416,21 @@ run_aggregation (void *cls)
{
if ( (GNUNET_NO == reserves_idle) ||
(GNUNET_YES == test_mode) )
+ {
/* Possibly more to on reserves, go for it immediately */
+ GNUNET_assert (NULL == task);
task = GNUNET_SCHEDULER_add_now (&run_reserve_closures,
NULL);
+ }
else
+ {
/* FIXME(dold): We might want to read the duration to sleep from the config */
/* nothing to do, sleep for a minute and try again */
+ GNUNET_assert (NULL == task);
task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
&run_aggregation,
NULL);
+ }
}
return;
}
@@ -1451,6 +1465,7 @@ run_aggregation (void *cls)
"Serialization issue, trying again later!\n");
db_plugin->rollback (db_plugin->cls,
session);
+ GNUNET_assert (NULL == task);
task = GNUNET_SCHEDULER_add_now (&run_aggregation,
NULL);
return;
@@ -1515,6 +1530,7 @@ run_aggregation (void *cls)
session);
cleanup_au ();
/* start again */
+ GNUNET_assert (NULL == task);
task = GNUNET_SCHEDULER_add_now (&run_aggregation,
NULL);
return;
@@ -1531,6 +1547,7 @@ run_aggregation (void *cls)
(void) commit_or_warn (session);
cleanup_au ();
/* start again */
+ GNUNET_assert (NULL == task);
task = GNUNET_SCHEDULER_add_now (&run_aggregation,
NULL);
return;
@@ -1587,6 +1604,7 @@ run_aggregation (void *cls)
db_plugin->rollback (db_plugin->cls,
session);
/* start again */
+ GNUNET_assert (NULL == task);
task = GNUNET_SCHEDULER_add_now (&run_aggregation,
NULL);
return;
@@ -1613,6 +1631,7 @@ run_aggregation (void *cls)
/* try again */
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Commit issue for prepared wire data; trying again later!\n");
+ GNUNET_assert (NULL == task);
task = GNUNET_SCHEDULER_add_now (&run_aggregation,
NULL);
return;
@@ -1625,6 +1644,7 @@ run_aggregation (void *cls)
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Preparation complete, switching to transfer mode\n");
/* run alternative task: actually do wire transfer! */
+ GNUNET_assert (NULL == task);
task = GNUNET_SCHEDULER_add_now (&run_transfers,
NULL);
return;
@@ -1685,6 +1705,7 @@ wire_confirm_cb (void *cls,
if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
{
/* try again */
+ GNUNET_assert (NULL == task);
task = GNUNET_SCHEDULER_add_now (&run_aggregation,
NULL);
}
@@ -1703,6 +1724,7 @@ wire_confirm_cb (void *cls,
{
case GNUNET_DB_STATUS_SOFT_ERROR:
/* try again */
+ GNUNET_assert (NULL == task);
task = GNUNET_SCHEDULER_add_now (&run_aggregation,
NULL);
return;
@@ -1716,6 +1738,7 @@ wire_confirm_cb (void *cls,
"Wire transfer complete\n");
/* continue with #run_transfers(), just to guard
against the unlikely case that there are more. */
+ GNUNET_assert (NULL == task);
task = GNUNET_SCHEDULER_add_now (&run_transfers,
NULL);
return;
@@ -1846,6 +1869,7 @@ run_transfers (void *cls)
return;
case GNUNET_DB_STATUS_SOFT_ERROR:
/* try again */
+ GNUNET_assert (NULL == task);
task = GNUNET_SCHEDULER_add_now (&run_transfers,
NULL);
return;
@@ -1853,6 +1877,7 @@ run_transfers (void *cls)
/* no more prepared wire transfers, go back to aggregation! */
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"No more pending wire transfers, starting aggregation\n");
+ GNUNET_assert (NULL == task);
task = GNUNET_SCHEDULER_add_now (&run_aggregation,
NULL);
return;
@@ -1898,6 +1923,7 @@ run (void *cls,
return;
}
+ GNUNET_assert (NULL == task);
task = GNUNET_SCHEDULER_add_now (&run_transfers,
NULL);
GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
--
cgit v1.2.3
From 5a11839002b2f327fa35e8a1bf589bb77c54e3c1 Mon Sep 17 00:00:00 2001
From: Christian Grothoff
Date: Tue, 4 Feb 2020 15:47:57 +0100
Subject: add timetravel option for testing/debugging
---
src/auditor/taler-auditor.c | 2 ++
src/auditor/taler-wire-auditor.c | 2 ++
src/exchange-tools/taler-exchange-keyup.c | 2 ++
src/exchange-tools/taler-exchange-wire.c | 2 ++
src/exchange/taler-exchange-aggregator.c | 2 ++
src/exchange/taler-exchange-httpd.c | 2 ++
src/exchange/taler-exchange-wirewatch.c | 4 +++-
7 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/src/auditor/taler-auditor.c b/src/auditor/taler-auditor.c
index 4e32d2a4..0ec5e2d7 100644
--- a/src/auditor/taler-auditor.c
+++ b/src/auditor/taler-auditor.c
@@ -5709,6 +5709,8 @@ main (int argc,
"restart",
"restart audit from the beginning (required on first run)",
&restart),
+ GNUNET_GETOPT_option_timetravel ('T',
+ "timetravel"),
GNUNET_GETOPT_OPTION_END
};
diff --git a/src/auditor/taler-wire-auditor.c b/src/auditor/taler-wire-auditor.c
index 94fd773c..5a68f165 100644
--- a/src/auditor/taler-wire-auditor.c
+++ b/src/auditor/taler-wire-auditor.c
@@ -2312,6 +2312,8 @@ main (int argc,
"restart",
"restart audit from the beginning (required on first run)",
&restart),
+ GNUNET_GETOPT_option_timetravel ('T',
+ "timetravel"),
GNUNET_GETOPT_OPTION_END
};
diff --git a/src/exchange-tools/taler-exchange-keyup.c b/src/exchange-tools/taler-exchange-keyup.c
index 266c1bac..f70ff23a 100644
--- a/src/exchange-tools/taler-exchange-keyup.c
+++ b/src/exchange-tools/taler-exchange-keyup.c
@@ -1437,6 +1437,8 @@ main (int argc,
"DKH",
"revoke denomination key hash (DKH) and request wallets to initiate /recoup",
&revoke_dkh),
+ GNUNET_GETOPT_option_timetravel ('T',
+ "timetravel"),
GNUNET_GETOPT_option_absolute_time ('t',
"time",
"TIMESTAMP",
diff --git a/src/exchange-tools/taler-exchange-wire.c b/src/exchange-tools/taler-exchange-wire.c
index 5ddc2404..0d6cdddb 100644
--- a/src/exchange-tools/taler-exchange-wire.c
+++ b/src/exchange-tools/taler-exchange-wire.c
@@ -228,6 +228,8 @@ main (int argc,
char *const *argv)
{
const struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_option_timetravel ('T',
+ "timetravel"),
GNUNET_GETOPT_option_filename ('m',
"master-key",
"FILENAME",
diff --git a/src/exchange/taler-exchange-aggregator.c b/src/exchange/taler-exchange-aggregator.c
index a03eaff5..d380c391 100644
--- a/src/exchange/taler-exchange-aggregator.c
+++ b/src/exchange/taler-exchange-aggregator.c
@@ -1943,6 +1943,8 @@ main (int argc,
char *const *argv)
{
struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_option_timetravel ('T',
+ "timetravel"),
GNUNET_GETOPT_option_flag ('t',
"test",
"run in test mode and exit when idle",
diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c
index 666cec0c..426c4865 100644
--- a/src/exchange/taler-exchange-httpd.c
+++ b/src/exchange/taler-exchange-httpd.c
@@ -999,6 +999,8 @@ main (int argc,
"SECONDS",
"after how long do connections timeout by default (in seconds)",
&connection_timeout),
+ GNUNET_GETOPT_option_timetravel ('T',
+ "timetravel"),
#if HAVE_DEVELOPER
GNUNET_GETOPT_option_filename ('f',
"file-input",
diff --git a/src/exchange/taler-exchange-wirewatch.c b/src/exchange/taler-exchange-wirewatch.c
index 972cee34..69929e12 100644
--- a/src/exchange/taler-exchange-wirewatch.c
+++ b/src/exchange/taler-exchange-wirewatch.c
@@ -597,7 +597,9 @@ main (int argc,
char *const *argv)
{
struct GNUNET_GETOPT_CommandLineOption options[] = {
- GNUNET_GETOPT_option_flag ('T',
+ GNUNET_GETOPT_option_timetravel ('T',
+ "timetravel"),
+ GNUNET_GETOPT_option_flag ('t',
"test",
"run in test mode and exit when idle",
&test_mode),
--
cgit v1.2.3
From 9bfeec352b95873bc94b96947a8dd335838f3e8b Mon Sep 17 00:00:00 2001
From: Christian Grothoff
Date: Tue, 4 Feb 2020 20:57:11 +0100
Subject: fix #6065
---
src/exchange/taler-exchange-httpd_mhd.c | 9 ++--
src/exchange/taler-exchange-httpd_refresh_melt.c | 2 +-
src/exchange/taler-exchange-httpd_refresh_reveal.c | 2 +-
src/exchange/taler-exchange-httpd_refund.c | 57 ++++++++--------------
src/exchange/taler-exchange-httpd_reserve_status.c | 2 +-
.../taler-exchange-httpd_reserve_withdraw.c | 2 +-
src/exchange/taler-exchange-httpd_responses.c | 2 +-
src/include/taler_error_codes.h | 5 ++
8 files changed, 34 insertions(+), 47 deletions(-)
diff --git a/src/exchange/taler-exchange-httpd_mhd.c b/src/exchange/taler-exchange-httpd_mhd.c
index 53944b6a..0f2ce033 100644
--- a/src/exchange/taler-exchange-httpd_mhd.c
+++ b/src/exchange/taler-exchange-httpd_mhd.c
@@ -128,11 +128,10 @@ TEH_MHD_handler_send_json_pack_error (struct TEH_RequestHandler *rh,
(void) connection_cls;
(void) upload_data;
(void) upload_data_size;
- return TALER_MHD_reply_json_pack (connection,
- rh->response_code,
- "{s:s}",
- "error",
- rh->data);
+ return TALER_MHD_reply_with_error (connection,
+ rh->response_code,
+ TALER_EC_METHOD_INVALID,
+ rh->data);
}
diff --git a/src/exchange/taler-exchange-httpd_refresh_melt.c b/src/exchange/taler-exchange-httpd_refresh_melt.c
index 71200037..c7dc700f 100644
--- a/src/exchange/taler-exchange-httpd_refresh_melt.c
+++ b/src/exchange/taler-exchange-httpd_refresh_melt.c
@@ -69,7 +69,7 @@ reply_refresh_melt_insufficient_funds (struct MHD_Connection *connection,
return TALER_MHD_reply_json_pack (connection,
MHD_HTTP_CONFLICT,
"{s:s, s:I, s:o, s:o, s:o, s:o, s:o}",
- "error",
+ "hint",
"insufficient funds",
"code",
(json_int_t)
diff --git a/src/exchange/taler-exchange-httpd_refresh_reveal.c b/src/exchange/taler-exchange-httpd_refresh_reveal.c
index 3619f9a3..1e03c8e7 100644
--- a/src/exchange/taler-exchange-httpd_refresh_reveal.c
+++ b/src/exchange/taler-exchange-httpd_refresh_reveal.c
@@ -108,7 +108,7 @@ reply_refresh_reveal_mismatch (struct MHD_Connection *connection,
return TALER_MHD_reply_json_pack (connection,
MHD_HTTP_CONFLICT,
"{s:s, s:I, s:o}",
- "error", "commitment violation",
+ "hint", "commitment violation",
"code",
(json_int_t)
TALER_EC_REFRESH_REVEAL_COMMITMENT_VIOLATION,
diff --git a/src/exchange/taler-exchange-httpd_refund.c b/src/exchange/taler-exchange-httpd_refund.c
index 8c6e9030..8e24b9b4 100644
--- a/src/exchange/taler-exchange-httpd_refund.c
+++ b/src/exchange/taler-exchange-httpd_refund.c
@@ -82,28 +82,6 @@ reply_refund_success (struct MHD_Connection *connection,
}
-/**
- * Generate generic refund failure message. All the details
- * are in the @a response_code. The body can be empty.
- *
- * @param connection connection to the client
- * @param response_code response code to generate
- * @param ec taler error code to include
- * @return MHD result code
- */
-static int
-reply_refund_failure (struct MHD_Connection *connection,
- unsigned int response_code,
- enum TALER_ErrorCode ec)
-{
- return TALER_MHD_reply_json_pack (connection,
- response_code,
- "{s:s, s:I}",
- "hint", "refund failure",
- "code", (json_int_t) ec);
-}
-
-
/**
* Generate refund conflict failure message. Returns the
* transaction list @a tl with the details about the conflict.
@@ -194,9 +172,10 @@ refund_transaction (void *cls,
if (0 > qs)
{
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
- *mhd_ret = reply_refund_failure (connection,
- MHD_HTTP_NOT_FOUND,
- TALER_EC_REFUND_COIN_NOT_FOUND);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_REFUND_COIN_NOT_FOUND,
+ "database transaction failure");
return qs;
}
deposit_found = GNUNET_NO;
@@ -319,9 +298,10 @@ refund_transaction (void *cls,
GNUNET_break_op (0); /* currency mismatch */
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
- *mhd_ret = reply_refund_failure (connection,
- MHD_HTTP_PRECONDITION_FAILED,
- TALER_EC_REFUND_CURRENCY_MISSMATCH);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_PRECONDITION_FAILED,
+ TALER_EC_REFUND_CURRENCY_MISSMATCH,
+ "currencies involved do not match");
return GNUNET_DB_STATUS_HARD_ERROR;
}
@@ -353,9 +333,10 @@ refund_transaction (void *cls,
/* money was already transferred to merchant, can no longer refund */
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
- *mhd_ret = reply_refund_failure (connection,
- MHD_HTTP_GONE,
- TALER_EC_REFUND_MERCHANT_ALREADY_PAID);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_GONE,
+ TALER_EC_REFUND_MERCHANT_ALREADY_PAID,
+ "money already sent to merchant");
return GNUNET_DB_STATUS_HARD_ERROR;
}
@@ -366,9 +347,10 @@ refund_transaction (void *cls,
GNUNET_break_op (0); /* cannot refund more than original value */
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
- *mhd_ret = reply_refund_failure (connection,
- MHD_HTTP_PRECONDITION_FAILED,
- TALER_EC_REFUND_INSUFFICIENT_FUNDS);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_PRECONDITION_FAILED,
+ TALER_EC_REFUND_INSUFFICIENT_FUNDS,
+ "refund requested exceeds original value");
return GNUNET_DB_STATUS_HARD_ERROR;
}
/* Check refund fee matches fee of denomination key! */
@@ -481,9 +463,10 @@ verify_and_execute_refund (struct MHD_Connection *connection,
if (0 > qs)
{
GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
- return reply_refund_failure (connection,
- MHD_HTTP_NOT_FOUND,
- TALER_EC_REFUND_COIN_NOT_FOUND);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_REFUND_COIN_NOT_FOUND,
+ "denomination of coin to be refunded not found in DB");
}
}
diff --git a/src/exchange/taler-exchange-httpd_reserve_status.c b/src/exchange/taler-exchange-httpd_reserve_status.c
index 89bf8b38..e2d35aae 100644
--- a/src/exchange/taler-exchange-httpd_reserve_status.c
+++ b/src/exchange/taler-exchange-httpd_reserve_status.c
@@ -164,7 +164,7 @@ TEH_RESERVE_handler_reserve_status (struct TEH_RequestHandler *rh,
return TALER_MHD_reply_json_pack (connection,
MHD_HTTP_NOT_FOUND,
"{s:s, s:s, s:I}",
- "error", "Reserve not found",
+ "hint", "Reserve not found",
"parameter", "reserve_pub",
"code",
(json_int_t)
diff --git a/src/exchange/taler-exchange-httpd_reserve_withdraw.c b/src/exchange/taler-exchange-httpd_reserve_withdraw.c
index 86633cd9..9daad0a0 100644
--- a/src/exchange/taler-exchange-httpd_reserve_withdraw.c
+++ b/src/exchange/taler-exchange-httpd_reserve_withdraw.c
@@ -74,7 +74,7 @@ reply_reserve_withdraw_insufficient_funds (struct MHD_Connection *connection,
return TALER_MHD_reply_json_pack (connection,
MHD_HTTP_CONFLICT,
"{s:s, s:I, s:o, s:o}",
- "error", "Insufficient funds",
+ "hint", "insufficient funds",
"code",
(json_int_t)
TALER_EC_WITHDRAW_INSUFFICIENT_FUNDS,
diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c
index c88a8a25..90ca14c8 100644
--- a/src/exchange/taler-exchange-httpd_responses.c
+++ b/src/exchange/taler-exchange-httpd_responses.c
@@ -446,7 +446,7 @@ TEH_RESPONSE_reply_coin_insufficient_funds (struct MHD_Connection *connection,
return TALER_MHD_reply_json_pack (connection,
MHD_HTTP_CONFLICT,
"{s:s, s:I, s:o}",
- "error", "insufficient funds",
+ "hint", "insufficient funds",
"code", (json_int_t) ec,
"history", history);
}
diff --git a/src/include/taler_error_codes.h b/src/include/taler_error_codes.h
index ac7f9288..917ac36d 100644
--- a/src/include/taler_error_codes.h
+++ b/src/include/taler_error_codes.h
@@ -80,6 +80,11 @@ enum TALER_ErrorCode
*/
TALER_EC_JSON_ALLOCATION_FAILURE = 7,
+ /**
+ * HTTP method invalid for this URL.
+ */
+ TALER_EC_METHOD_INVALID = 8,
+
/**
* The exchange failed to even just initialize its connection to the
* database. This response is provided with HTTP status code
--
cgit v1.2.3
From e6d6987e5685b35f6c3137f59894a02a63d09766 Mon Sep 17 00:00:00 2001
From: Christian Grothoff
Date: Tue, 4 Feb 2020 21:49:18 +0100
Subject: capitalization of option changed
---
src/testing/testing_api_cmd_exec_wirewatch.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/testing/testing_api_cmd_exec_wirewatch.c b/src/testing/testing_api_cmd_exec_wirewatch.c
index 44de9683..7a1a27a5 100644
--- a/src/testing/testing_api_cmd_exec_wirewatch.c
+++ b/src/testing/testing_api_cmd_exec_wirewatch.c
@@ -67,7 +67,7 @@ wirewatch_run (void *cls,
"taler-exchange-wirewatch",
"taler-exchange-wirewatch",
"-c", ws->config_filename,
- "-T", /* exit when done */
+ "-t", /* exit when done */
NULL);
if (NULL == ws->wirewatch_proc)
{
--
cgit v1.2.3
From 42bc31744b9810509aef344c54bfee2f4e2a7ccb Mon Sep 17 00:00:00 2001
From: Christian Grothoff
Date: Tue, 4 Feb 2020 21:59:43 +0100
Subject: implement /config in fakebank and taler_bank_lib.h (#6066)
---
src/bank-lib/Makefile.am | 1 +
src/bank-lib/bank_api_config.c | 255 +++++++++++++++++++++++++++
src/bank-lib/fakebank.c | 63 ++++++-
src/bank-lib/taler-fakebank-run.c | 28 ++-
src/benchmark/taler-exchange-benchmark.c | 36 ++--
src/include/taler_bank_service.h | 73 +++++++-
src/include/taler_fakebank_lib.h | 4 +-
src/include/taler_testing_lib.h | 8 +-
src/testing/test_bank_api.c | 36 +++-
src/testing/test_taler_exchange_aggregator.c | 78 ++++----
src/testing/testing_api_helpers_bank.c | 7 +-
src/testing/testing_api_helpers_exchange.c | 2 +-
src/testing/testing_api_loop.c | 88 +++++----
13 files changed, 564 insertions(+), 115 deletions(-)
create mode 100644 src/bank-lib/bank_api_config.c
diff --git a/src/bank-lib/Makefile.am b/src/bank-lib/Makefile.am
index 729f96e1..7227ad06 100644
--- a/src/bank-lib/Makefile.am
+++ b/src/bank-lib/Makefile.am
@@ -38,6 +38,7 @@ libtalerbank_la_LDFLAGS = \
libtalerbank_la_SOURCES = \
bank_api_admin.c \
bank_api_common.c bank_api_common.h \
+ bank_api_config.c \
bank_api_credit.c \
bank_api_debit.c \
bank_api_transfer.c \
diff --git a/src/bank-lib/bank_api_config.c b/src/bank-lib/bank_api_config.c
new file mode 100644
index 00000000..a84e4ff8
--- /dev/null
+++ b/src/bank-lib/bank_api_config.c
@@ -0,0 +1,255 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2017--2020 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 3,
+ or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public
+ License along with TALER; see the file COPYING. If not,
+ see
+*/
+/**
+ * @file bank-lib/bank_api_config.c
+ * @brief Implementation of the /config request
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "bank_api_common.h"
+#include /* just for HTTP status codes */
+#include "taler_signatures.h"
+
+/**
+ * Protocol version we implement.
+ */
+#define BANK_PROTOCOL_CURRENT 0
+
+/**
+ * How many revisions back are we compatible to.
+ */
+#define BANK_PROTOCOL_AGE 0
+
+
+/**
+ * @brief A /config Handle
+ */
+struct TALER_BANK_ConfigHandle
+{
+
+ /**
+ * The url for this request.
+ */
+ char *request_url;
+
+ /**
+ * Handle for the request.
+ */
+ struct GNUNET_CURL_Job *job;
+
+ /**
+ * Function to call with the result.
+ */
+ TALER_BANK_ConfigCallback hcb;
+
+ /**
+ * Closure for @a cb.
+ */
+ void *hcb_cls;
+};
+
+
+/**
+ * Parse configuration given in JSON format and invoke the callback on each item.
+ *
+ * @param ch handle to the account configuration request
+ * @param config JSON object with the configuration
+ * @return #GNUNET_OK if configuration was valid and @a rconfiguration and @a balance
+ * were set,
+ * #GNUNET_SYSERR if there was a protocol violation in @a configuration
+ */
+static int
+parse_config (struct TALER_BANK_ConfigHandle *ch,
+ const json_t *config)
+{
+ struct TALER_BANK_Configuration cfg;
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_string ("version",
+ &cfg.version),
+ GNUNET_JSON_spec_string ("currency",
+ &cfg.version),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (config,
+ spec,
+ NULL, NULL))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ ch->hcb (ch->hcb_cls,
+ MHD_HTTP_OK,
+ TALER_EC_NONE,
+ &cfg);
+ GNUNET_JSON_parse_free (spec);
+ return GNUNET_OK;
+}
+
+
+/**
+ * Function called when we're done processing the
+ * HTTP /config request.
+ *
+ * @param cls the `struct TALER_BANK_ConfigHandle`
+ * @param response_code HTTP response code, 0 on error
+ * @param response parsed JSON result, NULL on error
+ */
+static void
+handle_configuration_finished (void *cls,
+ long response_code,
+ const void *response)
+{
+ struct TALER_BANK_ConfigHandle *ch = cls;
+ enum TALER_ErrorCode ec;
+ const json_t *j = response;
+
+ ch->job = NULL;
+ switch (response_code)
+ {
+ case 0:
+ ec = TALER_EC_INVALID_RESPONSE;
+ break;
+ case MHD_HTTP_OK:
+ if (GNUNET_OK !=
+ parse_config (ch,
+ j))
+ {
+ GNUNET_break_op (0);
+ response_code = 0;
+ ec = TALER_EC_INVALID_RESPONSE;
+ break;
+ }
+ response_code = MHD_HTTP_NO_CONTENT; /* signal end of list */
+ ec = TALER_EC_NONE;
+ break;
+ case MHD_HTTP_BAD_REQUEST:
+ /* This should never happen, either us or the bank is buggy
+ (or API version conflict); just pass JSON reply to the application */
+ GNUNET_break_op (0);
+ ec = TALER_JSON_get_error_code (j);
+ break;
+ case MHD_HTTP_UNAUTHORIZED:
+ /* Nothing really to verify, bank says the HTTP Authentication
+ failed. May happen if HTTP authentication is used and the
+ user supplied a wrong username/password combination. */
+ ec = TALER_JSON_get_error_code (j);
+ break;
+ case MHD_HTTP_INTERNAL_SERVER_ERROR:
+ /* Server had an internal issue; we should retry, but this API
+ leaves this to the application */
+ ec = TALER_JSON_get_error_code (j);
+ break;
+ default:
+ /* unexpected response code */
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unexpected response code %u\n",
+ (unsigned int) response_code);
+ GNUNET_break_op (0);
+ ec = TALER_JSON_get_error_code (j);
+ response_code = 0;
+ break;
+ }
+ ch->hcb (ch->hcb_cls,
+ response_code,
+ ec,
+ NULL);
+ TALER_BANK_configuration_cancel (ch);
+}
+
+
+/**
+ * Request the configuration of the bank.
+ *
+ * @param ctx curl context for the event loop
+ * @param auth authentication data to use
+ * @param hres_cb the callback to call with the
+ * configuration
+ * @param hres_cb_cls closure for the above callback
+ * @return NULL if the inputs are invalid
+ */
+struct TALER_BANK_ConfigHandle *
+TALER_BANK_configuration (struct GNUNET_CURL_Context *ctx,
+ const struct TALER_BANK_AuthenticationData *auth,
+ TALER_BANK_ConfigCallback hres_cb,
+ void *hres_cb_cls)
+{
+ struct TALER_BANK_ConfigHandle *ch;
+ CURL *eh;
+
+ ch = GNUNET_new (struct TALER_BANK_ConfigHandle);
+ ch->hcb = hres_cb;
+ ch->hcb_cls = hres_cb_cls;
+ ch->request_url = TALER_url_join (auth->wire_gateway_url,
+ "config",
+ NULL);
+ if (NULL == ch->request_url)
+ {
+ GNUNET_free (ch);
+ GNUNET_break (0);
+ return NULL;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Requesting configuration at `%s'\n",
+ ch->request_url);
+ eh = curl_easy_init ();
+ if ( (GNUNET_OK !=
+ TALER_BANK_setup_auth_ (eh,
+ auth)) ||
+ (CURLE_OK !=
+ curl_easy_setopt (eh,
+ CURLOPT_URL,
+ ch->request_url)) )
+ {
+ GNUNET_break (0);
+ TALER_BANK_configuration_cancel (ch);
+ curl_easy_cleanup (eh);
+ return NULL;
+ }
+ ch->job = GNUNET_CURL_job_add2 (ctx,
+ eh,
+ NULL,
+ &handle_configuration_finished,
+ ch);
+ return ch;
+}
+
+
+/**
+ * Cancel a configuration request. This function cannot be
+ * used on a request handle if a response is already
+ * served for it.
+ *
+ * @param ch the configuration request handle
+ */
+void
+TALER_BANK_configuration_cancel (struct TALER_BANK_ConfigHandle *ch)
+{
+ if (NULL != ch->job)
+ {
+ GNUNET_CURL_job_cancel (ch->job);
+ ch->job = NULL;
+ }
+ GNUNET_free (ch->request_url);
+ GNUNET_free (ch);
+}
+
+
+/* end of bank_api_config.c */
diff --git a/src/bank-lib/fakebank.c b/src/bank-lib/fakebank.c
index abf48687..56af11f8 100644
--- a/src/bank-lib/fakebank.c
+++ b/src/bank-lib/fakebank.c
@@ -26,6 +26,24 @@
#include "taler_bank_service.h"
#include "taler_mhd_lib.h"
+/**
+ * Taler protocol version in the format CURRENT:REVISION:AGE
+ * as used by GNU libtool. See
+ * https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html
+ *
+ * Please be very careful when updating and follow
+ * https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html#Updating-version-info
+ * precisely. Note that this version has NOTHING to do with the
+ * release version, and the format is NOT the same that semantic
+ * versioning uses either.
+ *
+ * When changing this version, you likely want to also update
+ * #BANK_PROTOCOL_CURRENT and #BANK_PROTOCOL_AGE in
+ * bank_api_config.c!
+ */
+#define BANK_PROTOCOL_VERSION "0:0:0"
+
+
/**
* Maximum POST request size (for /admin/add-incoming)
*/
@@ -172,6 +190,11 @@ struct TALER_FAKEBANK_Handle
*/
uint64_t serial_counter;
+ /**
+ * Currency used by the fakebank.
+ */
+ char *currency;
+
/**
* BaseURL of the fakebank.
*/
@@ -527,6 +550,7 @@ TALER_FAKEBANK_stop (struct TALER_FAKEBANK_Handle *h)
h->mhd_bank = NULL;
}
GNUNET_free (h->my_baseurl);
+ GNUNET_free (h->currency);
GNUNET_free (h);
}
@@ -776,7 +800,7 @@ handle_transfer (struct TALER_FAKEBANK_Handle *h,
/**
- * Handle incoming HTTP request for /history
+ * Handle incoming HTTP request for / (home page).
*
* @param h the fakebank handle
* @param connection the connection
@@ -808,6 +832,29 @@ handle_home_page (struct TALER_FAKEBANK_Handle *h,
}
+/**
+ * Handle incoming HTTP request for /config
+ *
+ * @param h the fakebank handle
+ * @param connection the connection
+ * @param con_cls place to store state, not used
+ * @return MHD result code
+ */
+static int
+handle_config (struct TALER_FAKEBANK_Handle *h,
+ struct MHD_Connection *connection,
+ void **con_cls)
+{
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:s, s:s}",
+ "currency",
+ h->currency,
+ "version"
+ BANK_PROTOCOL_VERSION);
+}
+
+
/**
* This is the "base" structure for both the /history and the
* /history-range API calls.
@@ -1202,6 +1249,13 @@ serve (struct TALER_FAKEBANK_Handle *h,
return handle_home_page (h,
connection,
con_cls);
+ if ( (0 == strcmp (url,
+ "/config")) &&
+ (0 == strcasecmp (method,
+ MHD_HTTP_METHOD_GET)) )
+ return handle_config (h,
+ connection,
+ con_cls);
if ( (0 == strcmp (url,
"/admin/add-incoming")) &&
(0 == strcasecmp (method,
@@ -1433,15 +1487,19 @@ run_mhd (void *cls)
* would have issued the correct wire transfer orders.
*
* @param port port to listen to
+ * @param currency currency the bank uses
* @return NULL on error
*/
struct TALER_FAKEBANK_Handle *
-TALER_FAKEBANK_start (uint16_t port)
+TALER_FAKEBANK_start (uint16_t port,
+ const char *currency)
{
struct TALER_FAKEBANK_Handle *h;
+ GNUNET_assert (strlen (currency) < TALER_CURRENCY_LEN);
h = GNUNET_new (struct TALER_FAKEBANK_Handle);
h->port = port;
+ h->currency = GNUNET_strdup (currency);
GNUNET_asprintf (&h->my_baseurl,
"http://localhost:%u/",
(unsigned int) port);
@@ -1462,6 +1520,7 @@ TALER_FAKEBANK_start (uint16_t port)
MHD_OPTION_END);
if (NULL == h->mhd_bank)
{
+ GNUNET_free (h->currency);
GNUNET_free (h);
return NULL;
}
diff --git a/src/bank-lib/taler-fakebank-run.c b/src/bank-lib/taler-fakebank-run.c
index 55b3da54..588777c9 100644
--- a/src/bank-lib/taler-fakebank-run.c
+++ b/src/bank-lib/taler-fakebank-run.c
@@ -43,12 +43,38 @@ run (void *cls,
const char *cfgfile,
const struct GNUNET_CONFIGURATION_Handle *cfg)
{
+ char *currency_string;
+
(void) cls;
(void) args;
(void) cfgfile;
(void) cfg;
- if (NULL == TALER_FAKEBANK_start (8082))
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_string (cfg,
+ "taler",
+ "CURRENCY",
+ ¤cy_string))
+ {
+ GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+ "taler",
+ "CURRENCY");
+ ret = 1;
+ return;
+ }
+ if (strlen (currency_string) >= TALER_CURRENCY_LEN)
+ {
+ GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+ "taler",
+ "CURRENCY",
+ "Value is too long");
+ GNUNET_free (currency_string);
+ ret = 1;
+ return;
+ }
+ if (NULL == TALER_FAKEBANK_start (8082,
+ currency_string))
ret = 1;
+ GNUNET_free (currency_string);
ret = 0;
}
diff --git a/src/benchmark/taler-exchange-benchmark.c b/src/benchmark/taler-exchange-benchmark.c
index bd4d3eaf..91ed5b04 100644
--- a/src/benchmark/taler-exchange-benchmark.c
+++ b/src/benchmark/taler-exchange-benchmark.c
@@ -156,9 +156,9 @@ static char *mode_str;
static enum BenchmarkMode mode;
/**
- * Config filename.
+ * Configuration.
*/
-static char *cfg_filename;
+static struct GNUNET_CONFIGURATION_Handle *cfg;
/**
* Currency used.
@@ -445,7 +445,8 @@ launch_fakebank (void *cls)
(void) cls;
fakebank
- = TALER_TESTING_run_fakebank (exchange_bank_account.wire_gateway_url);
+ = TALER_TESTING_run_fakebank (exchange_bank_account.wire_gateway_url,
+ currency);
if (NULL == fakebank)
{
GNUNET_break (0);
@@ -624,12 +625,11 @@ parallel_benchmark (TALER_TESTING_Main main_cb,
NULL == loglev ? "INFO" : loglev,
logfile);
- result = TALER_TESTING_setup
- (main_cb,
- main_cb_cls,
- cfg_filename,
- exchanged,
- GNUNET_YES);
+ result = TALER_TESTING_setup (main_cb,
+ main_cb_cls,
+ cfg,
+ exchanged,
+ GNUNET_YES);
if (GNUNET_OK != result)
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failure in child process test suite!\n");
@@ -746,7 +746,7 @@ int
main (int argc,
char *const *argv)
{
- struct GNUNET_CONFIGURATION_Handle *cfg;
+ char *cfg_filename = NULL;
struct GNUNET_GETOPT_CommandLineOption options[] = {
GNUNET_GETOPT_option_mandatory
(GNUNET_GETOPT_option_cfgfile (&cfg_filename)),
@@ -798,6 +798,7 @@ main (int argc,
argc,
argv)))
{
+ GNUNET_free_non_null (cfg_filename);
return BAD_CLI_ARG;
}
GNUNET_log_setup ("taler-exchange-benchmark",
@@ -814,6 +815,7 @@ main (int argc,
else
{
TALER_LOG_ERROR ("Unknown mode given: '%s'\n", mode_str);
+ GNUNET_free_non_null (cfg_filename);
return BAD_CONFIG_FILE;
}
if (NULL == cfg_filename)
@@ -825,8 +827,10 @@ main (int argc,
cfg_filename))
{
TALER_LOG_ERROR ("Could not parse configuration\n");
+ GNUNET_free (cfg_filename);
return BAD_CONFIG_FILE;
}
+ GNUNET_free (cfg_filename);
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
"taler",
@@ -839,6 +843,16 @@ main (int argc,
GNUNET_CONFIGURATION_destroy (cfg);
return BAD_CONFIG_FILE;
}
+
+ if (strlen (currency) >= TALER_CURRENCY_LEN)
+ {
+ GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+ "taler",
+ "CURRENCY",
+ "Value is too long");
+ GNUNET_CONFIGURATION_destroy (cfg);
+ return BAD_CONFIG_FILE;
+ }
if (howmany_clients > 10240)
{
TALER_LOG_ERROR ("-p option value given is too large\n");
@@ -950,11 +964,11 @@ main (int argc,
return BAD_CONFIG_FILE;
}
}
- GNUNET_CONFIGURATION_destroy (cfg);
result = parallel_benchmark (&run,
NULL,
cfg_filename);
+ GNUNET_CONFIGURATION_destroy (cfg);
/* If we're the exchange worker, we're done now. No need to print results */
if (MODE_EXCHANGE == mode)
diff --git a/src/include/taler_bank_service.h b/src/include/taler_bank_service.h
index 98a1017c..c9c93fac 100644
--- a/src/include/taler_bank_service.h
+++ b/src/include/taler_bank_service.h
@@ -89,6 +89,73 @@ struct TALER_BANK_AuthenticationData
};
+/* ********************* /config *********************** */
+
+/**
+ * @brief A /config Handle
+ */
+struct TALER_BANK_ConfigHandle;
+
+/**
+ * Configuration data provided by the bank.
+ */
+struct TALER_BANK_Configuration
+{
+ /**
+ * Current protocol version. Libtool style.
+ */
+ const char *version;
+
+ /**
+ * Currency used by the bank.
+ */
+ const char *currency;
+};
+
+
+/**
+ * Function called with configuration details from the bank.
+ *
+ * @param cls closure
+ * @param http status code
+ * @param ec taler error code
+ * @param config the configuration, NULL on error
+ */
+typedef void
+(*TALER_BANK_ConfigCallback)(void *cls,
+ unsigned int http_status,
+ enum TALER_ErrorCode ec,
+ const struct TALER_BANK_Configuration *config);
+
+/**
+ * Request the configuration of the bank.
+ *
+ * @param ctx curl context for the event loop
+ * @param auth authentication data to use
+ * @param hres_cb the callback to call with the
+ * configuration
+ * @param hres_cb_cls closure for the above callback
+ * @return NULL if the inputs are invalid (i.e. zero value for
+ * @e num_results). In this case, the callback is not
+ * called.
+ */
+struct TALER_BANK_ConfigHandle *
+TALER_BANK_configuration (struct GNUNET_CURL_Context *ctx,
+ const struct TALER_BANK_AuthenticationData *auth,
+ TALER_BANK_ConfigCallback hres_cb,
+ void *hres_cb_cls);
+
+
+/**
+ * Cancel a configuration request. This function cannot be
+ * used on a request handle if a response is already
+ * served for it.
+ *
+ * @param ch the configuration request handle
+ */
+void
+TALER_BANK_configuration_cancel (struct TALER_BANK_ConfigHandle *ch);
+
/* ********************* /admin/add/incoming *********************** */
@@ -160,7 +227,7 @@ TALER_BANK_admin_add_incoming_cancel (struct
TALER_BANK_AdminAddIncomingHandle *aai);
-/* ********************* /taler/transfer *********************** */
+/* ********************* /transfer *********************** */
/**
* Prepare for exeuction of a wire transfer.
@@ -243,7 +310,7 @@ TALER_BANK_execute_wire_transfer_cancel (struct
TALER_BANK_WireExecuteHandle *weh);
-/* ********************* /taler/credits *********************** */
+/* ********************* /history/incoming *********************** */
/**
* Handle for querying the bank for transactions
@@ -347,7 +414,7 @@ void
TALER_BANK_credit_history_cancel (struct TALER_BANK_CreditHistoryHandle *hh);
-/* ********************* /taler/debits *********************** */
+/* ********************* /history/outgoing *********************** */
/**
* Handle for querying the bank for transactions
diff --git a/src/include/taler_fakebank_lib.h b/src/include/taler_fakebank_lib.h
index 9324bdce..8601a8d8 100644
--- a/src/include/taler_fakebank_lib.h
+++ b/src/include/taler_fakebank_lib.h
@@ -44,10 +44,12 @@ struct TALER_FAKEBANK_Handle;
* would have issued the correct wire transfer orders.
*
* @param port port to listen to
+ * @param currency which currency should the bank offer
* @return NULL on error
*/
struct TALER_FAKEBANK_Handle *
-TALER_FAKEBANK_start (uint16_t port);
+TALER_FAKEBANK_start (uint16_t port,
+ const char *currency);
/**
diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h
index 0b3d1999..5aa50155 100644
--- a/src/include/taler_testing_lib.h
+++ b/src/include/taler_testing_lib.h
@@ -635,7 +635,7 @@ typedef void
* @param main_cb the "run" method which coontains all the
* commands.
* @param main_cb_cls a closure for "run", typically NULL.
- * @param config_filename configuration filename.
+ * @param cfg configuration to use
* @param exchanged exchange process handle: will be put in the
* state as some commands - e.g. revoke - need to send
* signal to it, for example to let it know to reload the
@@ -650,7 +650,7 @@ typedef void
int
TALER_TESTING_setup (TALER_TESTING_Main main_cb,
void *main_cb_cls,
- const char *config_filename,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
struct GNUNET_OS_Process *exchanged,
int exchange_connect);
@@ -789,11 +789,13 @@ TALER_TESTING_run_bank (const char *config_filename,
* from the base URL.
*
* @param bank_url bank's base URL.
+ * @param currency currency the bank uses
* @return the fakebank process handle, or NULL if any
* error occurs.
*/
struct TALER_FAKEBANK_Handle *
-TALER_TESTING_run_fakebank (const char *bank_url);
+TALER_TESTING_run_fakebank (const char *bank_url,
+ const char *currency);
/**
diff --git a/src/testing/test_bank_api.c b/src/testing/test_bank_api.c
index bdafdc5f..75e22b59 100644
--- a/src/testing/test_bank_api.c
+++ b/src/testing/test_bank_api.c
@@ -52,6 +52,7 @@ static struct GNUNET_OS_Process *bankd;
*/
static int with_fakebank;
+
/**
* Main function that will tell the interpreter what commands to
* run.
@@ -116,12 +117,32 @@ run (void *cls,
}
+/**
+ * Runs #TALER_TESTING_setup() using the configuration.
+ *
+ * @param cls unused
+ * @param cfg configuration to use
+ * @return status code
+ */
+static int
+setup_with_cfg (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ (void) cls;
+ return TALER_TESTING_setup (&run,
+ NULL,
+ cfg,
+ NULL,
+ GNUNET_NO);
+}
+
+
int
main (int argc,
char *const *argv)
{
- int rv;
const char *cfgfilename;
+ int rv;
/* These environment variables get in the way... */
unsetenv ("XDG_DATA_HOME");
@@ -165,12 +186,13 @@ main (int argc,
return 77;
}
}
-
- rv = (GNUNET_OK == TALER_TESTING_setup (&run,
- NULL,
- cfgfilename,
- NULL,
- GNUNET_NO)) ? 0 : 1;
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_parse_and_run (cfgfilename,
+ &setup_with_cfg,
+ NULL))
+ rv = 1;
+ else
+ rv = 0;
if (GNUNET_NO == with_fakebank)
{
diff --git a/src/testing/test_taler_exchange_aggregator.c b/src/testing/test_taler_exchange_aggregator.c
index c709e5fe..2e8a35ce 100644
--- a/src/testing/test_taler_exchange_aggregator.c
+++ b/src/testing/test_taler_exchange_aggregator.c
@@ -57,36 +57,6 @@ static char *config_filename;
#define USER42_ACCOUNT "42"
-/**
- * @return GNUNET_NO if database could not be prepared,
- * otherwise GNUNET_OK
- */
-static int
-prepare_database (void *cls,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
-{
- dbc.plugin = TALER_EXCHANGEDB_plugin_load (cfg);
- if (NULL == dbc.plugin)
- {
- GNUNET_break (0);
- result = 77;
- return GNUNET_NO;
- }
- if (GNUNET_OK !=
- dbc.plugin->create_tables (dbc.plugin->cls))
- {
- GNUNET_break (0);
- TALER_EXCHANGEDB_plugin_unload (dbc.plugin);
- dbc.plugin = NULL;
- result = 77;
- return GNUNET_NO;
- }
- dbc.session = dbc.plugin->get_session (dbc.plugin->cls);
- GNUNET_assert (NULL != dbc.session);
-
- return GNUNET_OK;
-}
-
/**
* Collects all the tests.
@@ -454,6 +424,48 @@ run (void *cls,
}
+/**
+ * Prepare database an launch the test.
+ *
+ * @param cls unused
+ * @param cfg our configuration
+ * @return #GNUNET_NO if database could not be prepared,
+ * otherwise #GNUNET_OK
+ */
+static int
+prepare_database (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ dbc.plugin = TALER_EXCHANGEDB_plugin_load (cfg);
+ if (NULL == dbc.plugin)
+ {
+ GNUNET_break (0);
+ result = 77;
+ return GNUNET_NO;
+ }
+ if (GNUNET_OK !=
+ dbc.plugin->create_tables (dbc.plugin->cls))
+ {
+ GNUNET_break (0);
+ TALER_EXCHANGEDB_plugin_unload (dbc.plugin);
+ dbc.plugin = NULL;
+ result = 77;
+ return GNUNET_NO;
+ }
+ dbc.session = dbc.plugin->get_session (dbc.plugin->cls);
+ GNUNET_assert (NULL != dbc.session);
+
+ result = TALER_TESTING_setup (&run,
+ NULL,
+ cfg,
+ NULL, // no exchange process handle.
+ GNUNET_NO); // do not try to connect to the exchange
+
+
+ return GNUNET_OK;
+}
+
+
int
main (int argc,
char *const argv[])
@@ -507,12 +519,6 @@ main (int argc,
return result;
}
- result = TALER_TESTING_setup (&run,
- NULL,
- config_filename,
- NULL, // no exchange process handle.
- GNUNET_NO); // do not try to connect to the exchange
-
GNUNET_free (config_filename);
GNUNET_free (testname);
dbc.plugin->drop_tables (dbc.plugin->cls);
diff --git a/src/testing/testing_api_helpers_bank.c b/src/testing/testing_api_helpers_bank.c
index 7b8b203a..35ef4792 100644
--- a/src/testing/testing_api_helpers_bank.c
+++ b/src/testing/testing_api_helpers_bank.c
@@ -36,11 +36,13 @@
* from the base URL.
*
* @param bank_url bank's base URL.
+ * @param currency currency the bank uses
* @return the fakebank process handle, or NULL if any
* error occurs.
*/
struct TALER_FAKEBANK_Handle *
-TALER_TESTING_run_fakebank (const char *bank_url)
+TALER_TESTING_run_fakebank (const char *bank_url,
+ const char *currency)
{
const char *port;
long pnum;
@@ -56,7 +58,8 @@ TALER_TESTING_run_fakebank (const char *bank_url)
"Starting Fakebank on port %u (%s)\n",
(unsigned int) pnum,
bank_url);
- fakebankd = TALER_FAKEBANK_start ((uint16_t) pnum);
+ fakebankd = TALER_FAKEBANK_start ((uint16_t) pnum,
+ currency);
if (NULL == fakebankd)
{
GNUNET_break (0);
diff --git a/src/testing/testing_api_helpers_exchange.c b/src/testing/testing_api_helpers_exchange.c
index 29c96db1..911bc6f0 100644
--- a/src/testing/testing_api_helpers_exchange.c
+++ b/src/testing/testing_api_helpers_exchange.c
@@ -788,7 +788,7 @@ TALER_TESTING_setup_with_exchange_cfg (void *cls,
/* NOTE: this call blocks. */
result = TALER_TESTING_setup (setup_ctx->main_cb,
setup_ctx->main_cb_cls,
- setup_ctx->config_filename,
+ cfg,
exchanged,
GNUNET_YES);
GNUNET_break (0 ==
diff --git a/src/testing/testing_api_loop.c b/src/testing/testing_api_loop.c
index 61b95c2e..e9ccdb81 100644
--- a/src/testing/testing_api_loop.c
+++ b/src/testing/testing_api_loop.c
@@ -124,7 +124,33 @@ TALER_TESTING_run_with_fakebank (struct TALER_TESTING_Interpreter *is,
struct TALER_TESTING_Command *commands,
const char *bank_url)
{
- is->fakebank = TALER_TESTING_run_fakebank (bank_url);
+ char *currency;
+
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_string (is->cfg,
+ "taler",
+ "CURRENCY",
+ ¤cy))
+ {
+ GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+ "taler",
+ "CURRENCY");
+ is->result = GNUNET_SYSERR;
+ return;
+ }
+ if (strlen (currency) >= TALER_CURRENCY_LEN)
+ {
+ GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+ "taler",
+ "CURRENCY",
+ "Value is too long");
+ GNUNET_free (currency);
+ is->result = GNUNET_SYSERR;
+ return;
+ }
+ is->fakebank = TALER_TESTING_run_fakebank (bank_url,
+ currency);
+ GNUNET_free (currency);
if (NULL == is->fakebank)
{
GNUNET_break (0);
@@ -529,14 +555,6 @@ struct MainContext
*/
struct TALER_TESTING_Interpreter *is;
- /**
- * Configuration filename. The wrapper uses it to fetch
- * the exchange port number; We could have passed the port
- * number here, but having the config filename seems more
- * generic.
- */
- const char *config_filename;
-
/**
* URL of the exchange.
*/
@@ -683,18 +701,16 @@ do_abort (void *cls)
* and responsible to run the "run" method.
*
* @param cls a `struct MainContext *`
- * @param cfg configuration to use
*/
-static int
-main_exchange_connect_with_cfg (void *cls,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
+static void
+main_wrapper_exchange_connect (void *cls)
{
struct MainContext *main_ctx = cls;
struct TALER_TESTING_Interpreter *is = main_ctx->is;
char *exchange_url;
if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (cfg,
+ GNUNET_CONFIGURATION_get_value_string (is->cfg,
"exchange",
"BASE_URL",
&exchange_url))
@@ -702,40 +718,18 @@ main_exchange_connect_with_cfg (void *cls,
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"exchange",
"BASE_URL");
- return GNUNET_SYSERR;
+ return;
}
main_ctx->exchange_url = exchange_url;
- is->cfg = cfg;
is->timeout_task = GNUNET_SCHEDULER_add_shutdown (&do_abort,
main_ctx);
GNUNET_break
- (NULL != (is->exchange = TALER_EXCHANGE_connect
- (is->ctx,
- exchange_url,
- &TALER_TESTING_cert_cb,
- main_ctx,
- TALER_EXCHANGE_OPTION_END)));
- is->cfg = NULL;
- return GNUNET_OK;
-}
-
-
-/**
- * Initialize scheduler loop and curl context for the testcase,
- * and responsible to run the "run" method.
- *
- * @param cls a `struct MainContext *`
- */
-static void
-main_wrapper_exchange_connect (void *cls)
-{
- struct MainContext *main_ctx = cls;
-
- GNUNET_break (GNUNET_OK ==
- GNUNET_CONFIGURATION_parse_and_run (main_ctx->config_filename,
- &
- main_exchange_connect_with_cfg,
- main_ctx));
+ (NULL != (is->exchange =
+ TALER_EXCHANGE_connect (is->ctx,
+ exchange_url,
+ &TALER_TESTING_cert_cb,
+ main_ctx,
+ TALER_EXCHANGE_OPTION_END)));
}
@@ -746,7 +740,7 @@ main_wrapper_exchange_connect (void *cls)
* @param main_cb the "run" method which contains all the
* commands.
* @param main_cb_cls a closure for "run", typically NULL.
- * @param config_filename configuration filename.
+ * @param cfg configuration to use
* @param exchanged exchange process handle: will be put in the
* state as some commands - e.g. revoke - need to send
* signal to it, for example to let it know to reload the
@@ -761,7 +755,7 @@ main_wrapper_exchange_connect (void *cls)
int
TALER_TESTING_setup (TALER_TESTING_Main main_cb,
void *main_cb_cls,
- const char *config_filename,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
struct GNUNET_OS_Process *exchanged,
int exchange_connect)
{
@@ -771,9 +765,6 @@ TALER_TESTING_setup (TALER_TESTING_Main main_cb,
.main_cb_cls = main_cb_cls,
/* needed to init the curl ctx */
.is = &is,
- /* needed to read values like exchange port
- * number to construct the exchange url.*/
- .config_filename = config_filename
};
struct GNUNET_SIGNAL_Context *shc_chld;
@@ -781,6 +772,7 @@ TALER_TESTING_setup (TALER_TESTING_Main main_cb,
0,
sizeof (is));
is.exchanged = exchanged;
+ is.cfg = cfg;
sigpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO,
GNUNET_NO, GNUNET_NO);
GNUNET_assert (NULL != sigpipe);
--
cgit v1.2.3
From 2590db50d59602980a09d48280f69e1662eb3168 Mon Sep 17 00:00:00 2001
From: Christian Grothoff
Date: Tue, 4 Feb 2020 22:19:01 +0100
Subject: add shell script to revoke DK as requested by Florian for revocation
testing via taler-wallet-cli
---
contrib/taler-exchange-revoke | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
create mode 100755 contrib/taler-exchange-revoke
diff --git a/contrib/taler-exchange-revoke b/contrib/taler-exchange-revoke
new file mode 100755
index 00000000..8ce0e878
--- /dev/null
+++ b/contrib/taler-exchange-revoke
@@ -0,0 +1,24 @@
+#!/bin/sh
+# This file is in the public domain
+#
+# Used to first revoke a key and then restart the exchange
+# to ensure it notices the revocation.
+#
+# Takes 2 arguments:
+# $1: the configuration file name
+# $2: the denomination key hash (DKH) of the denomination to revoke
+
+set -eu
+
+if [ "$#" -ne 2 ];
+then
+ echo "illegal number of parameters"
+ exit 1
+fi
+
+taler-exchange-keyup -c $1 -r $2
+
+EXCHANGE_PID=`ps x | grep taler-exchange-httpd | awk '{print $1}'`
+kill -HUP $EXCHANGE_PID
+
+exit 0
--
cgit v1.2.3
From b33260432540561e3bb6f78e5a37ec7e1dae9fd4 Mon Sep 17 00:00:00 2001
From: Christian Grothoff
Date: Tue, 4 Feb 2020 22:37:49 +0100
Subject: extra checks, add to build system
---
contrib/Makefile.am | 3 ++-
contrib/taler-bank-manage-testing | 6 ++++++
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/contrib/Makefile.am b/contrib/Makefile.am
index f9de7a75..c38a1630 100644
--- a/contrib/Makefile.am
+++ b/contrib/Makefile.am
@@ -1,7 +1,8 @@
SUBDIRS = . tos pp
bin_SCRIPTS = \
- taler-bank-manage-testing
+ taler-bank-manage-testing \
+ taler-exchange-revoke
EXTRA_DIST = \
$(bin_SCRIPTS) \
diff --git a/contrib/taler-bank-manage-testing b/contrib/taler-bank-manage-testing
index b7e356d4..29494e3a 100755
--- a/contrib/taler-bank-manage-testing
+++ b/contrib/taler-bank-manage-testing
@@ -10,6 +10,12 @@
set -eu
+if [ "$#" -ne 3 ];
+then
+ echo "illegal number of parameters"
+ exit 1
+fi
+
# Ensure starting accounts exist
taler-bank-manage -c $1 --with-db $2 django provide_accounts
taler-bank-manage -c $1 --with-db $2 django add_bank_account 42
--
cgit v1.2.3
From 9e0a813b38b791a0bc020b8f1ee16d2b5d8712c6 Mon Sep 17 00:00:00 2001
From: Christian Grothoff
Date: Wed, 5 Feb 2020 21:11:57 +0100
Subject: implement auditor's exchange signing key caching (#6052)
---
src/auditor/taler-auditor-httpd.c | 7 +-
.../taler-auditor-httpd_deposit-confirmation.c | 131 +++++++++++++++------
.../taler-auditor-httpd_deposit-confirmation.h | 12 ++
3 files changed, 113 insertions(+), 37 deletions(-)
diff --git a/src/auditor/taler-auditor-httpd.c b/src/auditor/taler-auditor-httpd.c
index 4d5537e5..043d5b14 100644
--- a/src/auditor/taler-auditor-httpd.c
+++ b/src/auditor/taler-auditor-httpd.c
@@ -594,7 +594,7 @@ main (int argc,
if (GNUNET_OK !=
auditor_serve_process_config ())
return 1;
-
+ TEAH_DEPOSIT_CONFIRMATION_init ();
/* check for systemd-style FD passing */
listen_pid = getenv ("LISTEN_PID");
listen_fds = getenv ("LISTEN_FDS");
@@ -635,7 +635,10 @@ main (int argc,
fh = TALER_MHD_open_unix_path (serve_unixpath,
unixpath_mode);
if (-1 == fh)
+ {
+ TEAH_DEPOSIT_CONFIRMATION_done ();
return 1;
+ }
}
mhd
@@ -659,6 +662,7 @@ main (int argc,
{
fprintf (stderr,
"Failed to start HTTP server.\n");
+ TEAH_DEPOSIT_CONFIRMATION_done ();
return 1;
}
@@ -732,6 +736,7 @@ main (int argc,
break;
}
TALER_AUDITORDB_plugin_unload (TAH_plugin);
+ TEAH_DEPOSIT_CONFIRMATION_done ();
return (GNUNET_SYSERR == ret) ? 1 : 0;
}
diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation.c b/src/auditor/taler-auditor-httpd_deposit-confirmation.c
index 7759b553..87b1a26f 100644
--- a/src/auditor/taler-auditor-httpd_deposit-confirmation.c
+++ b/src/auditor/taler-auditor-httpd_deposit-confirmation.c
@@ -32,6 +32,19 @@
#include "taler-auditor-httpd_deposit-confirmation.h"
+/**
+ * Cache of already verified exchange signing keys. Maps the hash of the
+ * `struct TALER_ExchangeSigningKeyValidityPS` to the (static) string
+ * "verified". Access to this map is guarded by the #lock.
+ */
+static struct GNUNET_CONTAINER_MultiHashMap *cache;
+
+/**
+ * Lock for operations on #cache.
+ */
+static pthread_mutex_t lock;
+
+
/**
* We have parsed the JSON information about the deposit, do some
* basic sanity checks (especially that the signature on the coin is
@@ -55,6 +68,8 @@ verify_and_execute_deposit_confirmation (struct MHD_Connection *connection,
struct TALER_AUDITORDB_Session *session;
enum GNUNET_DB_QueryStatus qs;
struct GNUNET_TIME_Absolute now;
+ struct GNUNET_HashCode h;
+ int cached;
now = GNUNET_TIME_absolute_get ();
if ( (es->ep_start.abs_value_us > now.abs_value_us) ||
@@ -68,10 +83,6 @@ verify_and_execute_deposit_confirmation (struct MHD_Connection *connection,
"master_sig (expired)");
}
- /* TODO (#6052): consider having an in-memory cache of already
- verified exchange signing keys, this could save us
- a signature check AND a database transaction per
- operation. */
/* check exchange signing key signature */
skv.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY);
skv.purpose.size = htonl (sizeof (struct TALER_ExchangeSigningKeyValidityPS));
@@ -80,40 +91,64 @@ verify_and_execute_deposit_confirmation (struct MHD_Connection *connection,
skv.expire = GNUNET_TIME_absolute_hton (es->ep_expire);
skv.end = GNUNET_TIME_absolute_hton (es->ep_end);
skv.signkey_pub = es->exchange_pub;
- if (GNUNET_OK !=
- GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY,
- &skv.purpose,
- &es->master_sig.eddsa_signature,
- &es->master_public_key.eddsa_pub))
- {
- TALER_LOG_WARNING ("Invalid signature on exchange signing key\n");
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_FORBIDDEN,
- TALER_EC_DEPOSIT_CONFIRMATION_SIGNATURE_INVALID,
- "master_sig");
- }
- session = TAH_plugin->get_session (TAH_plugin->cls);
- if (NULL == session)
- {
- GNUNET_break (0);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_DB_SETUP_FAILED,
- "failed to establish session with database");
- }
- /* execute transaction */
- qs = TAH_plugin->insert_exchange_signkey (TAH_plugin->cls,
- session,
- es);
- if (0 > qs)
+ /* check our cache */
+ GNUNET_CRYPTO_hash (&skv,
+ sizeof (skv),
+ &h);
+ GNUNET_assert (0 == pthread_mutex_lock (&lock));
+ cached = GNUNET_CONTAINER_multihashmap_contains (cache,
+ &h);
+ GNUNET_assert (0 == pthread_mutex_unlock (&lock));
+
+ if (! cached)
{
- GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
- TALER_LOG_WARNING ("Failed to store exchange signing key in database\n");
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_AUDITOR_EXCHANGE_STORE_DB_ERROR,
- "failed to persist exchange signing key");
+ /* Not in cache, need to verify the signature, persist it, and possibly cache it */
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY,
+ &skv.purpose,
+ &es->master_sig.eddsa_signature,
+ &es->master_public_key.eddsa_pub))
+ {
+ TALER_LOG_WARNING ("Invalid signature on exchange signing key\n");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_FORBIDDEN,
+ TALER_EC_DEPOSIT_CONFIRMATION_SIGNATURE_INVALID,
+ "master_sig");
+ }
+
+ session = TAH_plugin->get_session (TAH_plugin->cls);
+ if (NULL == session)
+ {
+ GNUNET_break (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_DB_SETUP_FAILED,
+ "failed to establish session with database");
+ }
+ /* execute transaction */
+ qs = TAH_plugin->insert_exchange_signkey (TAH_plugin->cls,
+ session,
+ es);
+ if (0 > qs)
+ {
+ GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
+ TALER_LOG_WARNING ("Failed to store exchange signing key in database\n");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_AUDITOR_EXCHANGE_STORE_DB_ERROR,
+ "failed to persist exchange signing key");
+ }
+
+ /* Cache it, due to concurreny it might already be in the cache,
+ so we do not cache it twice but also don't insist on the 'put' to
+ succeed. */
+ GNUNET_assert (0 == pthread_mutex_lock (&lock));
+ (void) GNUNET_CONTAINER_multihashmap_put (cache,
+ &h,
+ "verified",
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+ GNUNET_assert (0 == pthread_mutex_unlock (&lock));
}
/* check deposit confirmation signature */
@@ -237,4 +272,28 @@ TAH_DEPOSIT_CONFIRMATION_handler (struct TAH_RequestHandler *rh,
}
+/**
+ * Initialize subsystem.
+ */
+void
+TEAH_DEPOSIT_CONFIRMATION_init (void)
+{
+ cache = GNUNET_CONTAINER_multihashmap_create (32,
+ GNUNET_NO);
+ GNUNET_assert (0 == pthread_mutex_init (&lock, NULL));
+}
+
+
+/**
+ * Shut down subsystem.
+ */
+void
+TEAH_DEPOSIT_CONFIRMATION_done (void)
+{
+ GNUNET_CONTAINER_multihashmap_destroy (cache);
+ cache = NULL;
+ GNUNET_assert (0 == pthread_mutex_destroy (&lock));
+}
+
+
/* end of taler-auditor-httpd_deposit-confirmation.c */
diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation.h b/src/auditor/taler-auditor-httpd_deposit-confirmation.h
index 842eb356..531f3c93 100644
--- a/src/auditor/taler-auditor-httpd_deposit-confirmation.h
+++ b/src/auditor/taler-auditor-httpd_deposit-confirmation.h
@@ -25,6 +25,18 @@
#include
#include "taler-auditor-httpd.h"
+/**
+ * Initialize subsystem.
+ */
+void
+TEAH_DEPOSIT_CONFIRMATION_init (void);
+
+/**
+ * Shut down subsystem.
+ */
+void
+TEAH_DEPOSIT_CONFIRMATION_done (void);
+
/**
* Handle a "/deposit-confirmation" request. Parses the JSON, and, if
--
cgit v1.2.3
From eae85d62c10907a71b9087866669a46907411023 Mon Sep 17 00:00:00 2001
From: Christian Grothoff
Date: Fri, 7 Feb 2020 00:44:35 +0100
Subject: proper i18n support for TOS
---
.gitignore | 1 +
configure.ac | 3 +-
contrib/Makefile.am | 34 +-
contrib/tos/.gitignore | 3 +
contrib/tos/Makefile | 109 +++++
contrib/tos/Makefile.am | 11 -
contrib/tos/README | 58 +++
contrib/tos/conf.py | 282 +++++++++++++
contrib/tos/en/0.docx | Bin 22460 -> 0 bytes
contrib/tos/en/0.epub | Bin 0 -> 16631 bytes
contrib/tos/en/0.html | 683 +++++++++++++++----------------
contrib/tos/en/0.pdf | Bin 0 -> 99867 bytes
contrib/tos/en/0.txt | 624 ++++++++++++++++------------
contrib/tos/en/0.xml | 344 ++++++++++++++++
contrib/tos/locale/de/LC_MESSAGES/tos.po | 514 +++++++++++++++++++++++
contrib/tos/tos.rst | 324 +++++++++++++++
contrib/update-tos.sh | 28 ++
17 files changed, 2380 insertions(+), 638 deletions(-)
create mode 100644 contrib/tos/.gitignore
create mode 100644 contrib/tos/Makefile
delete mode 100644 contrib/tos/Makefile.am
create mode 100644 contrib/tos/README
create mode 100644 contrib/tos/conf.py
delete mode 100644 contrib/tos/en/0.docx
create mode 100644 contrib/tos/en/0.epub
create mode 100644 contrib/tos/en/0.pdf
create mode 100644 contrib/tos/en/0.xml
create mode 100644 contrib/tos/locale/de/LC_MESSAGES/tos.po
create mode 100644 contrib/tos/tos.rst
create mode 100755 contrib/update-tos.sh
diff --git a/.gitignore b/.gitignore
index 1ac50e36..60f14174 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@
*app.info
*.gcno
*.gcda
+*.mo
.dirstamp
doc/coverage/
doc/taler-exchange.cps
diff --git a/configure.ac b/configure.ac
index 8e6b6f26..8b58bef0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -475,9 +475,8 @@ AM_CONDITIONAL([HAVE_TWISTER], [false])
AC_CONFIG_FILES([Makefile
contrib/Makefile
contrib/pp/Makefile
- contrib/tos/Makefile
doc/Makefile
- doc/doxygen/Makefile
+ doc/doxygen/Makefile
src/Makefile
src/auditor/Makefile
src/auditordb/Makefile
diff --git a/contrib/Makefile.am b/contrib/Makefile.am
index c38a1630..5a165d1f 100644
--- a/contrib/Makefile.am
+++ b/contrib/Makefile.am
@@ -1,4 +1,17 @@
-SUBDIRS = . tos pp
+SUBDIRS = . pp
+
+# English (en)
+tosendir=$(pkgdatadir)/tos/en
+
+# English (en)
+ppendir=$(pkgdatadir)/pp/en
+
+tosen_DATA = \
+ tos/en/0.txt \
+ tos/en/0.pdf \
+ tos/en/0.epub \
+ tos/en/0.xml \
+ tos/en/0.html
bin_SCRIPTS = \
taler-bank-manage-testing \
@@ -6,8 +19,27 @@ bin_SCRIPTS = \
EXTRA_DIST = \
$(bin_SCRIPTS) \
+ $(tosen_DATA) \
+ update-tos.sh \
+ tos/Makefile \
+ tos/README \
+ tos/tos.rst \
+ tos/conf.py \
+ tos/locale/de/LC_MESSAGES/tos.po \
auditor-report.tex.j2 \
coverage.sh \
gnunet.tag \
microhttpd.tag \
render.py
+
+# Change the set of supported languages here. You should
+# also update tos'XX'data and EXTRA_DIST accordingly.
+TOS_LANGUAGES="en de"
+
+# Change the terms-of-service version (Etag) to generate here!
+# This value should be incremented whenever there is a substantive
+# change in the original text (but not for the translations).
+TOS_VERSION=0
+
+update-tos:
+ VERSION=$(TOS_VERSION) ./update-tos.sh $(TOS_LANGUAGES)
diff --git a/contrib/tos/.gitignore b/contrib/tos/.gitignore
new file mode 100644
index 00000000..fb83616e
--- /dev/null
+++ b/contrib/tos/.gitignore
@@ -0,0 +1,3 @@
+sphinx.err
+sphinx.log
+_build/
diff --git a/contrib/tos/Makefile b/contrib/tos/Makefile
new file mode 100644
index 00000000..ab29543c
--- /dev/null
+++ b/contrib/tos/Makefile
@@ -0,0 +1,109 @@
+# Makefile for Sphinx documentation
+#
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = _build
+
+# User-friendly check for sphinx-build
+ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
+$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
+endif
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html json epub latex latexpdf text man doctest gettext
+
+help:
+ @echo "Please use \`make ' where is one of"
+ @echo " html to make a single large HTML file"
+ @echo " json to make JSON files"
+ @echo " epub to make an epub"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " pdf to make LaTeX files and run them through pdflatex"
+ @echo " txt to make text files"
+ @echo " man to make manual pages"
+ @echo " texinfo to make Texinfo files"
+ @echo " info to make Texinfo files and run them through makeinfo"
+ @echo " gettext to make PO message catalogs"
+ @echo " xml to make Docutils-native XML files"
+ @echo " pseudoxml to make pseudoxml-XML files for display purposes"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+ rm -rf $(BUILDDIR)/*
+
+
+# The html-linked builder does not support caching, so we
+# remove all cached state first.
+html:
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/html."
+
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+ @echo
+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+pdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/pdf
+ @echo "Running LaTeX files through pdflatex..."
+ $(MAKE) -C $(BUILDDIR)/pdf all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/pdf."
+
+txt:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/txt
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/txt."
+
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo
+ @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+ @echo "Run \`make' in that directory to run these through makeinfo" \
+ "(use \`make info' here to do that automatically)."
+
+info:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/info
+ @echo "Running Texinfo files through makeinfo..."
+ make -C $(BUILDDIR)/texinfo info
+ @echo "makeinfo finished; the Info files are in $(BUILDDIR)/info."
+
+gettext:
+ $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+ @echo
+ @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
+
+xml:
+ $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
+ @echo
+ @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
diff --git a/contrib/tos/Makefile.am b/contrib/tos/Makefile.am
deleted file mode 100644
index 1a86e408..00000000
--- a/contrib/tos/Makefile.am
+++ /dev/null
@@ -1,11 +0,0 @@
-
-# English (en)
-tosendir=$(pkgdatadir)/tos/en
-
-tosen_DATA = \
- en/0.txt \
- en/0.docx \
- en/0.html
-
-EXTRA_DIST = \
- $(tosen_DATA)
diff --git a/contrib/tos/README b/contrib/tos/README
new file mode 100644
index 00000000..fde5305b
--- /dev/null
+++ b/contrib/tos/README
@@ -0,0 +1,58 @@
+This directory contains the terms of service (template) for exchange
+operators.
+
+
+Dependencies
+============
+
+Generating new Terms of Service requires Sphinx, LaTeX with babel
+packages for all supported languages. On Debian, you should
+at least install:
+
+$ apt install python3-sphinx sphinx-intl texlive-lang-german texlive-lang-english
+
+(NOTE: List may be incomplete.)
+
+
+Updating the Terms of Service
+=============================
+
+The master file with the Terms of service is 'tos.rst'.
+
+If you make substantial changes, you MUST change the "TOS_VERSION"
+in contrib/Makefile.am to the new Etag.
+
+To begin the translation into other languages after editing the master
+file, run
+
+$ make gettext
+
+to generate the master PO file. Then, run
+
+$ sphinx-intl update -p _build/locale/ -l de -l fr -l it
+
+to update the PO files for the various languages (extend the list of
+languages as necessary). The PO files for the translators are kept
+at locale/$LANG/LC_MESSAGES/tos.po for the language $LANG.
+
+Once all PO files have been updated with new translations, run
+
+$ make update-tos
+
+in the "contrib/" directory to generate all of the formats. The
+respective make rule calls the '../update-tos.sh' script in the
+contrib/ directory, which calls the 'Makefile' in the tos/
+directory for the various supported languages and file formats
+and then moves the generated files to the target directory
+('contrib/tos/$LANG/$VERSION.$FORMAT')
+
+
+Adding a new language
+=====================
+
+To add a new language $LANG, add $LANG to "TOS_LANGUAGES" in
+'contrib/Makefile.am' and run
+
+$ sphinx-intl update -p _build/gettext -l $LANG
+
+to generate the PO template.
diff --git a/contrib/tos/conf.py b/contrib/tos/conf.py
new file mode 100644
index 00000000..29392556
--- /dev/null
+++ b/contrib/tos/conf.py
@@ -0,0 +1,282 @@
+"""
+ This file is part of GNU TALER.
+ Copyright (C) 2014-2020 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Lesser General Public License as published by the Free Software
+ Foundation; either version 2.1, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License along with
+ TALER; see the file COPYING. If not, see
+
+ @author Florian Dold
+ @author Benedikt Muller
+ @author Sree Harsha Totakura
+ @author Marcello Stanisci
+"""
+# -*- coding: utf-8 -*-
+#
+# neuro documentation build configuration file, created by
+# sphinx-quickstart on Sat May 31 13:11:06 2014.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys
+import os
+
+sys.path.append(os.path.abspath('_exts'))
+
+#import taler_sphinx_theme
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+needs_sphinx = '1.8.5'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+ 'sphinx.ext.todo',
+ 'sphinx.ext.imgmath',
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+source_suffix = {
+ '.rst': 'restructuredtext',
+}
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'tos'
+
+# General information about the project.
+project = u'tos'
+copyright = u'2014-2020 Taler Systems SA (GPLv3+ or GFDL 1.3+)'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '0'
+# The full version, including alpha/beta/rc tags.
+release = '0'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+# language = "en de"
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build', '_exts', 'cf', 'prebuilt']
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
+# default_role = "ts:type"
+
+locale_dirs = ['locale/']
+gettext_compact = False
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+# If true, keep warnings as "system message" paragraphs in the built documents.
+#keep_warnings = False
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'epub'
+
+#html_theme_path = taler_sphinx_theme.html_theme_path()
+
+#html_sidebars = {'**': ['logo-text.html', 'globaltoc.html', 'searchbox.html']}
+
+rst_epilog = ""
+
+html_show_sphinx = False
+
+html_theme_options = {
+ # Set the name of the project to appear in the sidebar
+ "relbar1": "false",
+ "footer": "false",
+}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# " v documentation".
+html_title = "Taler Terms of Service"
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+html_short_title = "Terms of Service"
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+# html_static_path = ['_static']
+
+# Add any extra paths that contain custom files (such as robots.txt or
+# .htaccess) here, relative to this directory. These files are copied
+# directly to the root of the documentation.
+#html_extra_path = []
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+html_show_sphinx = False
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+ # The paper size ('letterpaper' or 'a4paper').
+ #'papersize': 'letterpaper',
+
+ # The font size ('10pt', '11pt' or '12pt').
+ #'pointsize': '10pt',
+
+ # Additional stuff for the LaTeX preamble.
+ #'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+# author, documentclass [howto, manual, or own class]).
+latex_documents = [
+ ('tos', 'tos.tex',
+ 'Terms of Service', 'GNU Taler team', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+# latex_appendices = ["fdl-1.3"]
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+# -- Options for manual page output ---------------------------------------
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
+
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+#texinfo_no_detailmenu = False
+
+
+# -- Options for epub output ----------------------------
+
+epub_basename = "tos"
+
+epub_title = "Terms of Service"
diff --git a/contrib/tos/en/0.docx b/contrib/tos/en/0.docx
deleted file mode 100644
index 31c7022d..00000000
Binary files a/contrib/tos/en/0.docx and /dev/null differ
diff --git a/contrib/tos/en/0.epub b/contrib/tos/en/0.epub
new file mode 100644
index 00000000..a6c7860b
Binary files /dev/null and b/contrib/tos/en/0.epub differ
diff --git a/contrib/tos/en/0.html b/contrib/tos/en/0.html
index ea81db07..2c8000c3 100644
--- a/contrib/tos/en/0.html
+++ b/contrib/tos/en/0.html
@@ -1,364 +1,337 @@
-
-
-
-
-
-
-
-
-
-
-
Terms Of Service - Last Updated: 12.4.2019
-
- Welcome! Taler Systems SA (“we,” “our,” or “us”) provides a payment service
+
+
+
+
+
+ Terms Of Service — Taler Terms of Service
+
+
+
+
+
+
+
+
+
+
Welcome! Taler Systems SA (“we,” “our,” or “us”) provides a payment service
through our Internet presence (collectively the “Services”). Before using our
Services, please read the Terms of Service (the “Terms” or the “Agreement”)
-carefully.
-
-
Overview
-
- This
-section provides a brief summary of the highlights of this Agreement.
-Please note that when you accept this Agreement, you are accepting
-all of the terms and conditions and not just this section. We and
-possibly other third parties provide Internet services which interact
-with the Taler Wallet’s self-hosted personal payment application.
-When using the Taler Wallet to interact with our Services, you are
-agreeing to our Terms, so please read carefully.
-
-
Highlights:
-
-
You
- are responsible for keeping the data in your Taler Wallet at all
- times under your control. Any losses arising from you not being in
- control of your private information are your problem.
-
We
- will try to transfer funds we hold in escrow for our users to any
- legal recipient to the best of our ability within the limitations of
- the law and our implementation. However, the Services offered today
- are highly experimental and the set of recipients of funds is
- severely restricted.
-
For
- our Services, we may charge transaction fees. The specific fee
- structure is provided based on the Taler protocol and should be
- shown to you when you withdraw electronic coins using a Taler
- Wallet. You agree and understand that the Taler protocol allows for
- the fee structure to change.
-
You
- agree to not intentionally overwhelm our systems with requests and
- follow responsible disclosure if you find security issues in our
- services.
-
We
- cannot be held accountable for our Services not being available due
- to circumstances beyond our control. If we modify or terminate our
- services, we will try to give you the opportunity to recover your
- funds. However, given the experimental state of the Services today,
- this may not be possible. You are strongly advised to limit your use
- of the Service to small-scale experiments expecting total loss of
- all funds.
-
-
These
-terms outline approved uses of our Services. The Services and these
-Terms are still at an experimental stage. If you have any questions
-or comments related to this Agreement, please send us a message to
-legal@taler-systems.com. If you do not agree to this Agreement, you
-must not use our Services.
-
-
How you accept this policy
-
By
-sending funds to us (to top-up your Taler Wallet), you acknowledge
-that you have read, understood, and agreed to these Terms. We reserve
-the right to change these Terms at any time. If you disagree with the
-change, we may in the future offer you with an easy option to recover
-your unspent funds. However, in the current experimental period you
-acknowledge that this feature is not yet available, resulting in your
-funds being lost unless you accept the new Terms. If you continue to
-use our Services other than to recover your unspent funds, your
-continued use of our Services following any such change will signify
-your acceptance to be bound by the then current Terms. Please check
-the effective date above to determine if there have been any changes
-since you have last reviewed these Terms.
-
Services
-
We
-will try to transfer funds that we hold in escrow for our users to
-any legal recipient to the best of our ability and within the
-limitations of the law and our implementation. However, the Services
-offered today are highly experimental and the set of recipients of
-funds is severely restricted.
-
The
-Taler Wallet can be loaded by exchanging fiat currencies against
-electronic coins. We are providing this exchange service. Once your
-Taler Wallet is loaded with electronic coins they can be spent for
-purchases if the seller is accepting Taler as a means of payment. We
-are not guaranteeing that any seller is accepting Taler at all or a
-particular seller.
-
The
-seller or recipient of deposits of electronic coins must specify the
-target account, as per the design of the Taler protocol. They are
-responsible for following the protocol and specifying the correct
-bank account, and are solely liable for any losses that may arise
-from specifying the wrong account. We will allow the government to
-link wire transfers to the underlying contract hash. It is the
-responsibility of recipients to preserve the full contracts and to
-pay whatever taxes and charges may be applicable. Technical issues
-may lead to situations where we are unable to make transfers at all
-or lead to incorrect transfers that cannot be reversed. We will only
-refuse to execute transfers if the transfers are prohibited by a
-competent legal authority and we are ordered to do so.
-
-
-
-
-
-
FEES
-
You
-agree to pay the fees for exchanges and withdrawals completed via the
-Taler Wallet ("Fees") as defined by us, which we may change
-from time to time. With the exception of wire transfer fees, Taler
-transaction fees are set for any electronic coin at the time of
-withdrawal and fixed throughout the validity period of the respective
-electronic coin. Your wallet should obtain and display applicable
-fees when withdrawing funds. Fees for coins obtained as change may
-differ from the fees applicable to the original coin. Wire transfer
-fees that are independent from electronic coins may change annually.
-
-
You
-authorize us to charge or deduct applicable fees owed in connection
-with deposits, exchanges and withdrawals following the rules of the
-Taler protocol.
-
We
-reserve the right to provide different types of rewards to users
-either in the form of discount for our Services or in any other form
-at our discretion and without prior notice to you.
-
ELIGIBILITY
-
To
-be eligible to use our Services, you must be able to form legally
-binding contracts or have the permission of your legal guardian. By
-using our Services, you represent and warrant that you meet all
-eligibility requirements that we outline in these Terms.
-
-
FINANCIAL SELF-RESPONSIBILITY
-
You
-will be responsible for maintaining the availability, integrity and
-confidentiality of the data stored in your wallet. When you setup a
-Taler Wallet, you are strongly advised to follow the precautionary
-measures offered by the software to minimize the chances to losse
-access to or control over your Wallet data. We will not be liable for
-any loss or damage arising from your failure to comply with this
-paragraph.
-
-
COPYRIGHTS and TRADEMARKS
-
The
-Taler Wallet is released under the terms of the GNU General Public
-License (GNU GPL). You have the right to access, use, and share the
-Taler Wallet, in modified or unmodified form. However, the GPL is a
-strong copyleft license, which means that any derivative works must
-be distributed under the same license terms as the original software.
-If you have any questions, you should review the GNU GPL’s full
-terms and conditions at https://www.gnu.org/licenses/gpl-3.0.en.html.
-
-
"Taler"
-itself is a trademark of Taler Systems SA. You are welcome to use the
-name in relation to processing payments using the Taler protocol,
-assuming your use is compatible with an official release from the GNU
- Project that is not older than two years.
-
-
YOUR USE OF OUR SERVICES
-
When
-using our Services, you agree to not take any action that
-intentionally imposes an unreasonable load on our infrastructure. If
-you find security problems in our Services, you agree to first report
-them to security@taler-systems.com
-and grant us the right to publish your report. We warrant that we
-will ourselves publicly disclose any issues reported within 3 months,
-and that we will not prosecute anyone reporting security issues if
-they did not exploit the issue beyond a proof-of-concept, and
-followed the above responsible disclosure practice.
-
LIMITATION OF LIABILITY & DISCLAIMER OF WARRANTIES
-
You
-understand and agree that we have no control over, and no duty to
-take any action regarding: Failures, disruptions, errors, or delays
-in processing that you may experience while using our Services; The
-risk of failure of hardware, software, and Internet connections; The
-risk of malicious software being introduced or found in the software
-underlying the Taler Wallet; The risk that third parties may obtain
-unauthorized access to information stored within your Taler Wallet,
-including, but not limited to your Taler Wallet coins or backup
-encryption keys.
-
-
You
-release us from all liability related to any losses, damages, or
-claims arising from:
-
-
user error such as forgotten passwords, incorrectly constructed
+carefully.
+
This section provides a brief summary of the highlights of this
+Agreement. Please note that when you accept this Agreement, you are accepting
+all of the terms and conditions and not just this section. We and possibly
+other third parties provide Internet services which interact with the Taler
+Wallet’s self-hosted personal payment application. When using the Taler Wallet
+to interact with our Services, you are agreeing to our Terms, so please read
+carefully.
You are responsible for keeping the data in your Taler Wallet at all times
+under your control. Any losses arising from you not being in control of
+your private information are your problem.
+
We will try to transfer funds we hold in escrow for our users to any legal
+recipient to the best of our ability within the limitations of the law and
+our implementation. However, the Services offered today are highly
+experimental and the set of recipients of funds is severely restricted.
+
For our Services, we may charge transaction fees. The specific fee structure
+is provided based on the Taler protocol and should be shown to you when you
+withdraw electronic coins using a Taler Wallet. You agree and understand
+that the Taler protocol allows for the fee structure to change.
+
You agree to not intentionally overwhelm our systems with requests and
+follow responsible disclosure if you find security issues in our services.
+
We cannot be held accountable for our Services not being available due to
+circumstances beyond our control. If we modify or terminate our services,
+we will try to give you the opportunity to recover your funds. However,
+given the experimental state of the Services today, this may not be
+possible. You are strongly advised to limit your use of the Service
+to small-scale experiments expecting total loss of all funds.
+
+
+
These terms outline approved uses of our Services. The Services and these
+Terms are still at an experimental stage. If you have any questions or
+comments related to this Agreement, please send us a message to
+legal@taler-systems.com. If you do not agree to this Agreement, you must not
+use our Services.
By sending funds to us (to top-up your Taler Wallet), you acknowledge that you
+have read, understood, and agreed to these Terms. We reserve the right to
+change these Terms at any time. If you disagree with the change, we may in the
+future offer you with an easy option to recover your unspent funds. However,
+in the current experimental period you acknowledge that this feature is not
+yet available, resulting in your funds being lost unless you accept the new
+Terms. If you continue to use our Services other than to recover your unspent
+funds, your continued use of our Services following any such change will
+signify your acceptance to be bound by the then current Terms. Please check
+the effective date above to determine if there have been any changes since you
+have last reviewed these Terms.
We will try to transfer funds that we hold in escrow for our users to any
+legal recipient to the best of our ability and within the limitations of the
+law and our implementation. However, the Services offered today are highly
+experimental and the set of recipients of funds is severely restricted. The
+Taler Wallet can be loaded by exchanging fiat currencies against electronic
+coins. We are providing this exchange service. Once your Taler Wallet is
+loaded with electronic coins they can be spent for purchases if the seller is
+accepting Taler as a means of payment. We are not guaranteeing that any seller
+is accepting Taler at all or a particular seller. The seller or recipient of
+deposits of electronic coins must specify the target account, as per the
+design of the Taler protocol. They are responsible for following the protocol
+and specifying the correct bank account, and are solely liable for any losses
+that may arise from specifying the wrong account. We will allow the government
+to link wire transfers to the underlying contract hash. It is the
+responsibility of recipients to preserve the full contracts and to pay
+whatever taxes and charges may be applicable. Technical issues may lead to
+situations where we are unable to make transfers at all or lead to incorrect
+transfers that cannot be reversed. We will only refuse to execute transfers if
+the transfers are prohibited by a competent legal authority and we are ordered
+to do so.
You agree to pay the fees for exchanges and withdrawals completed via the
+Taler Wallet (“Fees”) as defined by us, which we may change from time to
+time. With the exception of wire transfer fees, Taler transaction fees are set
+for any electronic coin at the time of withdrawal and fixed throughout the
+validity period of the respective electronic coin. Your wallet should obtain
+and display applicable fees when withdrawing funds. Fees for coins obtained as
+change may differ from the fees applicable to the original coin. Wire transfer
+fees that are independent from electronic coins may change annually. You
+authorize us to charge or deduct applicable fees owed in connection with
+deposits, exchanges and withdrawals following the rules of the Taler protocol.
+We reserve the right to provide different types of rewards to users either in
+the form of discount for our Services or in any other form at our discretion
+and without prior notice to you.
To be eligible to use our Services, you must be able to form legally binding
+contracts or have the permission of your legal guardian. By using our
+Services, you represent and warrant that you meet all eligibility requirements
+that we outline in these Terms.
You will be responsible for maintaining the availability, integrity and
+confidentiality of the data stored in your wallet. When you setup a Taler
+Wallet, you are strongly advised to follow the precautionary measures offered
+by the software to minimize the chances to losse access to or control over
+your Wallet data. We will not be liable for any loss or damage arising from
+your failure to comply with this paragraph.
The Taler Wallet is released under the terms of the GNU General Public License
+(GNU GPL). You have the right to access, use, and share the Taler Wallet, in
+modified or unmodified form. However, the GPL is a strong copyleft license,
+which means that any derivative works must be distributed under the same
+license terms as the original software. If you have any questions, you should
+review the GNU GPL’s full terms and conditions at
+https://www.gnu.org/licenses/gpl-3.0.en.html. “Taler” itself is a trademark
+of Taler Systems SA. You are welcome to use the name in relation to processing
+payments using the Taler protocol, assuming your use is compatible with an
+official release from the GNU Project that is not older than two years.
When using our Services, you agree to not take any action that intentionally
+imposes an unreasonable load on our infrastructure. If you find security
+problems in our Services, you agree to first report them to
+security@taler-systems.com and grant us the right to publish your report. We
+warrant that we will ourselves publicly disclose any issues reported within 3
+months, and that we will not prosecute anyone reporting security issues if
+they did not exploit the issue beyond a proof-of-concept, and followed the
+above responsible disclosure practice.
+
+
+
Limitation of liability & disclaimer of warranties¶
+
You understand and agree that we have no control over, and no duty to take any
+action regarding: Failures, disruptions, errors, or delays in processing that
+you may experience while using our Services; The risk of failure of hardware,
+software, and Internet connections; The risk of malicious software being
+introduced or found in the software underlying the Taler Wallet; The risk that
+third parties may obtain unauthorized access to information stored within your
+Taler Wallet, including, but not limited to your Taler Wallet coins or backup
+encryption keys. You release us from all liability related to any losses,
+damages, or claims arising from:
+
+
user error such as forgotten passwords, incorrectly constructed
transactions;
-
server failure or data loss;
-
unauthorized access to the Taler Wallet application;
-
bugs or other errors in the Taler Wallet software; and
-
any unauthorized third party activities, including, but not limited
-to, the use of viruses, phishing, brute forcing, or other means of
-attack against the Taler Wallet. We make no representations
-concerning any Third Party Content contained in or accessed through
- our Services.
-
-
-Any
-other terms, conditions, warranties, or representations associated
-with such content, are solely between you and such organizations
-and/or individuals.
-
-
LIMITATION OF LIABILITY
-
-
To
-the fullest extent permitted by applicable law, in no event will we
-or any of our officers, directors, representatives, agents, servants,
-counsel, employees, consultants, lawyers, and other personnel
-authorized to act, acting, or purporting to act on our behalf
-(collectively the “Taler Parties”) be liable to you under
-contract, tort, strict liability, negligence, or any other legal or
- equitable theory, for:
-
-
-any lost profits, data loss, cost of procurement of substitute goods
-or services, or direct, indirect, incidental, special, punitive,
-compensatory, or consequential damages of any kind whatsoever
-resulting from:
-
-
- your use of, or conduct in connection with, our services;
-
-any unauthorized use of your wallet and/or private key due to your
+
server failure or data loss;
+
unauthorized access to the Taler Wallet application;
+
bugs or other errors in the Taler Wallet software; and
+
any unauthorized third party activities, including, but not limited to,
+the use of viruses, phishing, brute forcing, or other means of attack
+against the Taler Wallet. We make no representations concerning any
+Third Party Content contained in or accessed through our Services.
+
+
Any other terms, conditions, warranties, or representations associated with
+such content, are solely between you and such organizations and/or
+individuals.
To the fullest extent permitted by applicable law, in no event will we or any
+of our officers, directors, representatives, agents, servants, counsel,
+employees, consultants, lawyers, and other personnel authorized to act,
+acting, or purporting to act on our behalf (collectively the “Taler Parties”)
+be liable to you under contract, tort, strict liability, negligence, or any
+other legal or equitable theory, for:
+
+
any lost profits, data loss, cost of procurement of substitute goods or
+services, or direct, indirect, incidental, special, punitive, compensatory,
+or consequential damages of any kind whatsoever resulting from:
+
+
+
+
your use of, or conduct in connection with, our services;
+
any unauthorized use of your wallet and/or private key due to your
failure to maintain the confidentiality of your wallet;
-
any interruption or cessation of transmission to or from the
- services; or
-
any bugs, viruses, trojan horses, or the like that are found in the
-Taler Wallet software or that may be transmitted to or through our
-services by any third party (regardless of the source of
- origination)
+
any interruption or cessation of transmission to or from the services; or
+
any bugs, viruses, trojan horses, or the like that are found in the Taler
+Wallet software or that may be transmitted to or through our services by
+any third party (regardless of the source of origination), or
-
or any direct damages.
+
+
+
any direct damages.
-
-
These
-limitations apply regardless of legal theory, whether based on tort,
-strict liability, breach of contract, breach of warranty, or any
-other legal theory, and whether or not we were advised of the
-possibility of such damages. Some jurisdictions do not allow the
-exclusion or limitation of liability for consequential or incidental
-damages, so the above limitation may not apply to you.
-
-
WARRANTY DISCLAIMER
-
Our
-services are provided "as is" and without warranty of any
-kind. To the maximum extent permitted by law, we disclaim all
-representations and warranties, express or implied, relating to the
-services and underlying software or any content on the services,
-whether provided or owned by us or by any third party, including
-without limitation, warranties of merchantability, fitness for a
-particular purpose, title, non-infringement, freedom from computer
-virus, and any implied warranties arising from course of dealing,
+
These limitations apply regardless of legal theory, whether based on tort,
+strict liability, breach of contract, breach of warranty, or any other legal
+theory, and whether or not we were advised of the possibility of such
+damages. Some jurisdictions do not allow the exclusion or limitation of
+liability for consequential or incidental damages, so the above limitation may
+not apply to you.
Our services are provided “as is” and without warranty of any kind. To the
+maximum extent permitted by law, we disclaim all representations and
+warranties, express or implied, relating to the services and underlying
+software or any content on the services, whether provided or owned by us or by
+any third party, including without limitation, warranties of merchantability,
+fitness for a particular purpose, title, non-infringement, freedom from
+computer virus, and any implied warranties arising from course of dealing,
course of performance, or usage in trade, all of which are expressly
-disclaimed. In addition, we do not represent or warrant that the
-content accessible via the services is accurate, complete, available,
-current, free of viruses or other harmful components, or that the
-results of using the services will meet your requirements. Some
-states do not allow the disclaimer of implied warranties, so the
-foregoing disclaimers may not apply to you. This paragraph gives you
-specific legal rights and you may also have other legal rights that
-vary from state to state.
-
-
-
INDEMNITY
-
To
-the extent permitted by applicable law, you agree to defend,
-indemnify, and hold harmless the Taler Parties from and against any
-and all claims, damages, obligations, losses, liabilities, costs or
-debt, and expenses (including, but not limited to, attorney’s fees)
-arising from: (a) your use of and access to the Services; (b) any
-feedback or submissions you provide to us concerning the Taler
-Wallet; (c) your violation of any term of this Agreement; or (d) your
-violation of any law, rule, or regulation, or the rights of any third
-party.
-
-
TIME LIMITATION ON CLAIMS
-
You
-agree that any claim you may have arising out of or related to your
-relationship with us must be filed within one year after such claim
-arises, otherwise, your claim in permanently barred.
-
-
GOVERNING LAW
-
No
-matter where you’re located, the laws of Switzerland will govern
-these Terms. If any provisions of these Terms are inconsistent with
-any applicable law, those provisions will be superseded or modified
-only to the extent such provisions are inconsistent. The parties
-agree to submit to the ordinary courts in Zurich, Switzerland for
-exclusive jurisdiction of any dispute arising out of or related to
-your use of the Services or your breach of these Terms.
-
-
TERMINATION
-
-the event of termination concerning your use of our Services, your
-obligations under this Agreement will still continue.
-
-
DISCONTINUANCE OF SERVICES
-
We
-may, in our sole discretion and without cost to you, with or without
-prior notice, and at any time, modify or discontinue, temporarily or
-permanently, any portion of our Services. We will use the Taler
-protocol’s provisions to notify Wallets if our Services are to be
-discontinued. It is your responsibility to ensure that the Taler
-Wallet is online at least once every three months to observe these
-notifications. We shall not be held responsible or liable for any
-loss of funds in the event that we discontinue or depreciate the
-Services and your Taler Wallet fails to transfer out the coins within
- a three months notification period.
-
-
NO WAIVER
-
Our
-failure to exercise or delay in exercising any right, power, or
-privilege under this Agreement shall not operate as a waiver; nor
-shall any single or partial exercise of any right, power, or
-privilege preclude any other or further exercise thereof.
-
-
SEVERABILITY
-
If
-it turns out that any part of this Agreement is invalid, void, or for
-any reason unenforceable, that term will be deemed severable and
-limited or eliminated to the minimum extent necessary.
-
-
FORCE MAJEURE
-
We
-shall not be held liable for any delays, failure in performance, or
-interruptions of service which result directly or indirectly from any
-cause or condition beyond our reasonable control, including but not
-limited to: any delay or failure due to any act of God, act of civil
-or military authorities, act of terrorism, civil disturbance, war,
-strike or other labor dispute, fire, interruption in
-telecommunications or Internet services or network provider services,
-failure of equipment and/or software, other catastrophe, or any other
-occurrence which is beyond our reasonable control and shall not
-affect the validity and enforceability of any remaining provisions.
-
-
ASSIGNMENT
-
You
-agree that we may assign any of our rights and/or transfer,
-sub-contract, or delegate any of our obligations under these Terms.
-
-
ENTIRE AGREEMENT
-
This
-Agreement sets forth the entire understanding and agreement as to the
+disclaimed. In addition, we do not represent or warrant that the content
+accessible via the services is accurate, complete, available, current, free of
+viruses or other harmful components, or that the results of using the services
+will meet your requirements. Some states do not allow the disclaimer of
+implied warranties, so the foregoing disclaimers may not apply to you. This
+paragraph gives you specific legal rights and you may also have other legal
+rights that vary from state to state.
To the extent permitted by applicable law, you agree to defend, indemnify, and
+hold harmless the Taler Parties from and against any and all claims, damages,
+obligations, losses, liabilities, costs or debt, and expenses (including, but
+not limited to, attorney’s fees) arising from: (a) your use of and access to
+the Services; (b) any feedback or submissions you provide to us concerning the
+Taler Wallet; (c) your violation of any term of this Agreement; or (d) your
+violation of any law, rule, or regulation, or the rights of any third party.
You agree that any claim you may have arising out of or related to your
+relationship with us must be filed within one year after such claim arises,
+otherwise, your claim in permanently barred.
No matter where you’re located, the laws of Switzerland will govern these
+Terms. If any provisions of these Terms are inconsistent with any applicable
+law, those provisions will be superseded or modified only to the extent such
+provisions are inconsistent. The parties agree to submit to the ordinary
+courts in Zurich, Switzerland for exclusive jurisdiction of any dispute
+arising out of or related to your use of the Services or your breach of these
+Terms.
We may, in our sole discretion and without cost to you, with or without prior
+notice, and at any time, modify or discontinue, temporarily or permanently,
+any portion of our Services. We will use the Taler protocol’s provisions to
+notify Wallets if our Services are to be discontinued. It is your
+responsibility to ensure that the Taler Wallet is online at least once every
+three months to observe these notifications. We shall not be held responsible
+or liable for any loss of funds in the event that we discontinue or depreciate
+the Services and your Taler Wallet fails to transfer out the coins within a
+three months notification period.
Our failure to exercise or delay in exercising any right, power, or privilege
+under this Agreement shall not operate as a waiver; nor shall any single or
+partial exercise of any right, power, or privilege preclude any other or
+further exercise thereof.
If it turns out that any part of this Agreement is invalid, void, or for any
+reason unenforceable, that term will be deemed severable and limited or
+eliminated to the minimum extent necessary.
We shall not be held liable for any delays, failure in performance, or
+interruptions of service which result directly or indirectly from any cause or
+condition beyond our reasonable control, including but not limited to: any
+delay or failure due to any act of God, act of civil or military authorities,
+act of terrorism, civil disturbance, war, strike or other labor dispute, fire,
+interruption in telecommunications or Internet services or network provider
+services, failure of equipment and/or software, other catastrophe, or any
+other occurrence which is beyond our reasonable control and shall not affect
+the validity and enforceability of any remaining provisions.
This Agreement sets forth the entire understanding and agreement as to the
subject matter hereof and supersedes any and all prior discussions,
-agreements, and understandings of any kind (including, without
-limitation, any prior versions of this Agreement) and every nature
-between us. Except as provided for above, any modification to this
-Agreement must be in writing and must be signed by both parties.
-
-
QUESTIONS OR COMMENTS
-
We
-welcome comments, questions, concerns, or suggestions. Please send us
-a message on our contact page at legal@taler-systems.com.
-
-
-
+agreements, and understandings of any kind (including, without limitation, any
+prior versions of this Agreement) and every nature between us. Except as
+provided for above, any modification to this Agreement must be in writing and
+must be signed by both parties.
+
We welcome comments, questions, concerns, or suggestions. Please send us a
+message on our contact page at legal@taler-systems.com.
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/contrib/tos/en/0.pdf b/contrib/tos/en/0.pdf
new file mode 100644
index 00000000..972b91b9
Binary files /dev/null and b/contrib/tos/en/0.pdf differ
diff --git a/contrib/tos/en/0.txt b/contrib/tos/en/0.txt
index 5a5ee1b9..9b512f01 100644
--- a/contrib/tos/en/0.txt
+++ b/contrib/tos/en/0.txt
@@ -1,295 +1,381 @@
-Terms Of Service - Last Updated: 12.4.2019
+Terms Of Service
+****************
-Welcome! Taler Systems SA (“we,” “our,” or “us”) provides a payment service
-through our Internet presence (collectively the “Services”). Before using our
-Services, please read the Terms of Service (the “Terms” or the “Agreement”)
-carefully.
+Last Updated: 12.4.2019
-OVERVIEW
+Welcome! Taler Systems SA (“we,” “our,” or “us”) provides a payment
+service through our Internet presence (collectively the “Services”).
+Before using our Services, please read the Terms of Service (the
+“Terms” or the “Agreement”) carefully.
+
+
+Overview
+========
This section provides a brief summary of the highlights of this
-Agreement. Please note that when you accept this Agreement, you are accepting
-all of the terms and conditions and not just this section. We and possibly
-other third parties provide Internet services which interact with the Taler
-Wallet’s self-hosted personal payment application. When using the Taler Wallet
-to interact with our Services, you are agreeing to our Terms, so please read
-carefully.
+Agreement. Please note that when you accept this Agreement, you are
+accepting all of the terms and conditions and not just this section.
+We and possibly other third parties provide Internet services which
+interact with the Taler Wallet’s self-hosted personal payment
+application. When using the Taler Wallet to interact with our
+Services, you are agreeing to our Terms, so please read carefully.
+
Highlights:
- • You are responsible for keeping the data in your Taler Wallet at all times
- under your control. Any losses arising from you not being in control of
- your private information are your problem.
- • We will try to transfer funds we hold in escrow for our users to any legal
- recipient to the best of our ability within the limitations of the law and
- our implementation. However, the Services offered today are highly
- experimental and the set of recipients of funds is severely restricted.
- • For our Services, we may charge transaction fees. The specific fee structure
- is provided based on the Taler protocol and should be shown to you when you
- withdraw electronic coins using a Taler Wallet. You agree and understand
- that the Taler protocol allows for the fee structure to change.
- • You agree to not intentionally overwhelm our systems with requests and
- follow responsible disclosure if you find security issues in our services.
- • We cannot be held accountable for our Services not being available due to
- circumstances beyond our control. If we modify or terminate our services,
- we will try to give you the opportunity to recover your funds. However,
- given the experimental state of the Services today, this may not be
- possible. You are strongly advised to limit your use of the Service
- to small-scale experiments expecting total loss of all funds.
-
-These terms outline approved uses of our Services. The Services and these
-Terms are still at an experimental stage. If you have any questions or
-comments related to this Agreement, please send us a message to
-legal@taler-systems.com. If you do not agree to this Agreement, you must not
-use our Services.
-
-HOW YOU ACCEPT THIS POLICY
-
-By sending funds to us (to top-up your Taler Wallet), you acknowledge that you
-have read, understood, and agreed to these Terms. We reserve the right to
-change these Terms at any time. If you disagree with the change, we may in the
-future offer you with an easy option to recover your unspent funds. However,
-in the current experimental period you acknowledge that this feature is not
-yet available, resulting in your funds being lost unless you accept the new
-Terms. If you continue to use our Services other than to recover your unspent
-funds, your continued use of our Services following any such change will
-signify your acceptance to be bound by the then current Terms. Please check
-the effective date above to determine if there have been any changes since you
-have last reviewed these Terms.
-
-SERVICES
-
-We will try to transfer funds that we hold in escrow for our users to any
-legal recipient to the best of our ability and within the limitations of the
-law and our implementation. However, the Services offered today are highly
-experimental and the set of recipients of funds is severely restricted. The
-Taler Wallet can be loaded by exchanging fiat currencies against electronic
-coins. We are providing this exchange service. Once your Taler Wallet is
-loaded with electronic coins they can be spent for purchases if the seller is
-accepting Taler as a means of payment. We are not guaranteeing that any seller
-is accepting Taler at all or a particular seller. The seller or recipient of
-deposits of electronic coins must specify the target account, as per the
-design of the Taler protocol. They are responsible for following the protocol
-and specifying the correct bank account, and are solely liable for any losses
-that may arise from specifying the wrong account. We will allow the government
-to link wire transfers to the underlying contract hash. It is the
+-----------
+
+ * You are responsible for keeping the data in your Taler Wallet at
+ all times under your control. Any losses arising from you not
+ being in control of your private information are your problem.
+
+ * We will try to transfer funds we hold in escrow for our users to
+ any legal recipient to the best of our ability within the
+ limitations of the law and our implementation. However, the
+ Services offered today are highly experimental and the set of
+ recipients of funds is severely restricted.
+
+ * For our Services, we may charge transaction fees. The specific
+ fee structure is provided based on the Taler protocol and should
+ be shown to you when you withdraw electronic coins using a Taler
+ Wallet. You agree and understand that the Taler protocol allows
+ for the fee structure to change.
+
+ * You agree to not intentionally overwhelm our systems with
+ requests and follow responsible disclosure if you find security
+ issues in our services.
+
+ * We cannot be held accountable for our Services not being
+ available due to circumstances beyond our control. If we modify
+ or terminate our services, we will try to give you the
+ opportunity to recover your funds. However, given the
+ experimental state of the Services today, this may not be
+ possible. You are strongly advised to limit your use of the
+ Service to small-scale experiments expecting total loss of all
+ funds.
+
+These terms outline approved uses of our Services. The Services and
+these Terms are still at an experimental stage. If you have any
+questions or comments related to this Agreement, please send us a
+message to legal@taler-systems.com. If you do not agree to this
+Agreement, you must not use our Services.
+
+
+How you accept this policy
+==========================
+
+By sending funds to us (to top-up your Taler Wallet), you acknowledge
+that you have read, understood, and agreed to these Terms. We reserve
+the right to change these Terms at any time. If you disagree with the
+change, we may in the future offer you with an easy option to recover
+your unspent funds. However, in the current experimental period you
+acknowledge that this feature is not yet available, resulting in your
+funds being lost unless you accept the new Terms. If you continue to
+use our Services other than to recover your unspent funds, your
+continued use of our Services following any such change will signify
+your acceptance to be bound by the then current Terms. Please check
+the effective date above to determine if there have been any changes
+since you have last reviewed these Terms.
+
+
+Services
+========
+
+We will try to transfer funds that we hold in escrow for our users to
+any legal recipient to the best of our ability and within the
+limitations of the law and our implementation. However, the Services
+offered today are highly experimental and the set of recipients of
+funds is severely restricted. The Taler Wallet can be loaded by
+exchanging fiat currencies against electronic coins. We are providing
+this exchange service. Once your Taler Wallet is loaded with
+electronic coins they can be spent for purchases if the seller is
+accepting Taler as a means of payment. We are not guaranteeing that
+any seller is accepting Taler at all or a particular seller. The
+seller or recipient of deposits of electronic coins must specify the
+target account, as per the design of the Taler protocol. They are
+responsible for following the protocol and specifying the correct bank
+account, and are solely liable for any losses that may arise from
+specifying the wrong account. We will allow the government to link
+wire transfers to the underlying contract hash. It is the
responsibility of recipients to preserve the full contracts and to pay
-whatever taxes and charges may be applicable. Technical issues may lead to
-situations where we are unable to make transfers at all or lead to incorrect
-transfers that cannot be reversed. We will only refuse to execute transfers if
-the transfers are prohibited by a competent legal authority and we are ordered
-to do so.
-
-FEES
-
-You agree to pay the fees for exchanges and withdrawals completed via the
-Taler Wallet ("Fees") as defined by us, which we may change from time to
-time. With the exception of wire transfer fees, Taler transaction fees are set
-for any electronic coin at the time of withdrawal and fixed throughout the
-validity period of the respective electronic coin. Your wallet should obtain
-and display applicable fees when withdrawing funds. Fees for coins obtained as
-change may differ from the fees applicable to the original coin. Wire transfer
-fees that are independent from electronic coins may change annually. You
-authorize us to charge or deduct applicable fees owed in connection with
-deposits, exchanges and withdrawals following the rules of the Taler protocol.
-We reserve the right to provide different types of rewards to users either in
-the form of discount for our Services or in any other form at our discretion
-and without prior notice to you.
-
-ELIGIBILITY
-
-To be eligible to use our Services, you must be able to form legally binding
-contracts or have the permission of your legal guardian. By using our
-Services, you represent and warrant that you meet all eligibility requirements
-that we outline in these Terms.
-
-FINANCIAL SELF-RESPONSIBILITY
-
-You will be responsible for maintaining the availability, integrity and
-confidentiality of the data stored in your wallet. When you setup a Taler
-Wallet, you are strongly advised to follow the precautionary measures offered
-by the software to minimize the chances to losse access to or control over
-your Wallet data. We will not be liable for any loss or damage arising from
-your failure to comply with this paragraph.
-
-COPYRIGHTS and TRADEMARKS
-
-The Taler Wallet is released under the terms of the GNU General Public License
-(GNU GPL). You have the right to access, use, and share the Taler Wallet, in
-modified or unmodified form. However, the GPL is a strong copyleft license,
-which means that any derivative works must be distributed under the same
-license terms as the original software. If you have any questions, you should
-review the GNU GPL’s full terms and conditions at
-https://www.gnu.org/licenses/gpl-3.0.en.html. “Taler” itself is a trademark
-of Taler Systems SA. You are welcome to use the name in relation to processing
-payments using the Taler protocol, assuming your use is compatible with an
-official release from the GNU Project that is not older than two years.
-
-YOUR USE OF OUR SERVICES
-
-When using our Services, you agree to not take any action that intentionally
-imposes an unreasonable load on our infrastructure. If you find security
-problems in our Services, you agree to first report them to
-security@taler-systems.com and grant us the right to publish your report. We
-warrant that we will ourselves publicly disclose any issues reported within 3
-months, and that we will not prosecute anyone reporting security issues if
-they did not exploit the issue beyond a proof-of-concept, and followed the
-above responsible disclosure practice.
-
-LIMITATION OF LIABILITY & DISCLAIMER OF WARRANTIES
-
-You understand and agree that we have no control over, and no duty to take any
-action regarding: Failures, disruptions, errors, or delays in processing that
-you may experience while using our Services; The risk of failure of hardware,
-software, and Internet connections; The risk of malicious software being
-introduced or found in the software underlying the Taler Wallet; The risk that
-third parties may obtain unauthorized access to information stored within your
-Taler Wallet, including, but not limited to your Taler Wallet coins or backup
-encryption keys. You release us from all liability related to any losses,
-damages, or claims arising from:
-
-(a) user error such as forgotten passwords, incorrectly constructed
- transactions;
-(b) server failure or data loss;
-(c) unauthorized access to the Taler Wallet application;
-(d) bugs or other errors in the Taler Wallet software; and
-(e) any unauthorized third party activities, including, but not limited to,
- the use of viruses, phishing, brute forcing, or other means of attack
- against the Taler Wallet. We make no representations concerning any
- Third Party Content contained in or accessed through our Services.
-
-Any other terms, conditions, warranties, or representations associated with
-such content, are solely between you and such organizations and/or
-individuals.
-
-LIMITATION OF LIABILITY
-
-To the fullest extent permitted by applicable law, in no event will we or any
-of our officers, directors, representatives, agents, servants, counsel,
-employees, consultants, lawyers, and other personnel authorized to act,
-acting, or purporting to act on our behalf (collectively the “Taler Parties”)
-be liable to you under contract, tort, strict liability, negligence, or any
-other legal or equitable theory, for:
-
-(a) any lost profits, data loss, cost of procurement of substitute goods or
- services, or direct, indirect, incidental, special, punitive, compensatory,
- or consequential damages of any kind whatsoever resulting from:
- (i) your use of, or conduct in connection with, our services;
- (ii) any unauthorized use of your wallet and/or private key due to your
- failure to maintain the confidentiality of your wallet;
- (iii) any interruption or cessation of transmission to or from the services; or
- (iv) any bugs, viruses, trojan horses, or the like that are found in the Taler
- Wallet software or that may be transmitted to or through our services by
- any third party (regardless of the source of origination), or
-(b) any direct damages.
-
-These limitations apply regardless of legal theory, whether based on tort,
-strict liability, breach of contract, breach of warranty, or any other legal
-theory, and whether or not we were advised of the possibility of such
-damages. Some jurisdictions do not allow the exclusion or limitation of
-liability for consequential or incidental damages, so the above limitation may
-not apply to you.
-
-WARRANTY DISCLAIMER
-
-Our services are provided "as is" and without warranty of any kind. To the
-maximum extent permitted by law, we disclaim all representations and
-warranties, express or implied, relating to the services and underlying
-software or any content on the services, whether provided or owned by us or by
-any third party, including without limitation, warranties of merchantability,
-fitness for a particular purpose, title, non-infringement, freedom from
-computer virus, and any implied warranties arising from course of dealing,
-course of performance, or usage in trade, all of which are expressly
-disclaimed. In addition, we do not represent or warrant that the content
-accessible via the services is accurate, complete, available, current, free of
-viruses or other harmful components, or that the results of using the services
-will meet your requirements. Some states do not allow the disclaimer of
-implied warranties, so the foregoing disclaimers may not apply to you. This
-paragraph gives you specific legal rights and you may also have other legal
-rights that vary from state to state.
-
-INDEMNITY
-
-To the extent permitted by applicable law, you agree to defend, indemnify, and
-hold harmless the Taler Parties from and against any and all claims, damages,
-obligations, losses, liabilities, costs or debt, and expenses (including, but
-not limited to, attorney’s fees) arising from: (a) your use of and access to
-the Services; (b) any feedback or submissions you provide to us concerning the
-Taler Wallet; (c) your violation of any term of this Agreement; or (d) your
-violation of any law, rule, or regulation, or the rights of any third party.
-
-TIME LIMITATION ON CLAIMS
-
-You agree that any claim you may have arising out of or related to your
-relationship with us must be filed within one year after such claim arises,
-otherwise, your claim in permanently barred.
-
-GOVERNING LAW
-
-No matter where you’re located, the laws of Switzerland will govern these
-Terms. If any provisions of these Terms are inconsistent with any applicable
-law, those provisions will be superseded or modified only to the extent such
-provisions are inconsistent. The parties agree to submit to the ordinary
-courts in Zurich, Switzerland for exclusive jurisdiction of any dispute
-arising out of or related to your use of the Services or your breach of these
-Terms.
-
-TERMINATION
+whatever taxes and charges may be applicable. Technical issues may
+lead to situations where we are unable to make transfers at all or
+lead to incorrect transfers that cannot be reversed. We will only
+refuse to execute transfers if the transfers are prohibited by a
+competent legal authority and we are ordered to do so.
+
+
+Fees
+====
+
+You agree to pay the fees for exchanges and withdrawals completed via
+the Taler Wallet ("Fees") as defined by us, which we may change from
+time to time. With the exception of wire transfer fees, Taler
+transaction fees are set for any electronic coin at the time of
+withdrawal and fixed throughout the validity period of the respective
+electronic coin. Your wallet should obtain and display applicable fees
+when withdrawing funds. Fees for coins obtained as change may differ
+from the fees applicable to the original coin. Wire transfer fees that
+are independent from electronic coins may change annually. You
+authorize us to charge or deduct applicable fees owed in connection
+with deposits, exchanges and withdrawals following the rules of the
+Taler protocol. We reserve the right to provide different types of
+rewards to users either in the form of discount for our Services or in
+any other form at our discretion and without prior notice to you.
+
+
+Eligibility
+===========
+
+To be eligible to use our Services, you must be able to form legally
+binding contracts or have the permission of your legal guardian. By
+using our Services, you represent and warrant that you meet all
+eligibility requirements that we outline in these Terms.
+
+
+Financial self-responsibility
+=============================
+
+You will be responsible for maintaining the availability, integrity
+and confidentiality of the data stored in your wallet. When you setup
+a Taler Wallet, you are strongly advised to follow the precautionary
+measures offered by the software to minimize the chances to losse
+access to or control over your Wallet data. We will not be liable for
+any loss or damage arising from your failure to comply with this
+paragraph.
+
+
+Copyrights and trademarks
+=========================
+
+The Taler Wallet is released under the terms of the GNU General Public
+License (GNU GPL). You have the right to access, use, and share the
+Taler Wallet, in modified or unmodified form. However, the GPL is a
+strong copyleft license, which means that any derivative works must be
+distributed under the same license terms as the original software. If
+you have any questions, you should review the GNU GPL’s full terms and
+conditions at https://www.gnu.org/licenses/gpl-3.0.en.html. “Taler”
+itself is a trademark of Taler Systems SA. You are welcome to use the
+name in relation to processing payments using the Taler protocol,
+assuming your use is compatible with an official release from the GNU
+Project that is not older than two years.
+
+
+Your use of our services
+========================
+
+When using our Services, you agree to not take any action that
+intentionally imposes an unreasonable load on our infrastructure. If
+you find security problems in our Services, you agree to first report
+them to security@taler-systems.com and grant us the right to publish
+your report. We warrant that we will ourselves publicly disclose any
+issues reported within 3 months, and that we will not prosecute anyone
+reporting security issues if they did not exploit the issue beyond a
+proof-of-concept, and followed the above responsible disclosure
+practice.
+
+
+Limitation of liability & disclaimer of warranties
+==================================================
+
+You understand and agree that we have no control over, and no duty to
+take any action regarding: Failures, disruptions, errors, or delays in
+processing that you may experience while using our Services; The risk
+of failure of hardware, software, and Internet connections; The risk
+of malicious software being introduced or found in the software
+underlying the Taler Wallet; The risk that third parties may obtain
+unauthorized access to information stored within your Taler Wallet,
+including, but not limited to your Taler Wallet coins or backup
+encryption keys. You release us from all liability related to any
+losses, damages, or claims arising from:
+
+1. user error such as forgotten passwords, incorrectly constructed
+ transactions;
+
+2. server failure or data loss;
+
+3. unauthorized access to the Taler Wallet application;
+
+4. bugs or other errors in the Taler Wallet software; and
+
+5. any unauthorized third party activities, including, but not limited
+ to, the use of viruses, phishing, brute forcing, or other means of
+ attack against the Taler Wallet. We make no representations
+ concerning any Third Party Content contained in or accessed through
+ our Services.
+
+Any other terms, conditions, warranties, or representations associated
+with such content, are solely between you and such organizations
+and/or individuals.
+
+
+Limitation of liability
+=======================
+
+To the fullest extent permitted by applicable law, in no event will we
+or any of our officers, directors, representatives, agents, servants,
+counsel, employees, consultants, lawyers, and other personnel
+authorized to act, acting, or purporting to act on our behalf
+(collectively the “Taler Parties”) be liable to you under contract,
+tort, strict liability, negligence, or any other legal or equitable
+theory, for:
+
+1. any lost profits, data loss, cost of procurement of substitute
+ goods or services, or direct, indirect, incidental, special,
+ punitive, compensatory, or consequential damages of any kind
+ whatsoever resulting from:
+
+ 1. your use of, or conduct in connection with, our services;
+
+ 2. any unauthorized use of your wallet and/or private key due to
+ your failure to maintain the confidentiality of your wallet;
+
+ 3. any interruption or cessation of transmission to or from the
+ services; or
+
+ 4. any bugs, viruses, trojan horses, or the like that are found in
+ the Taler Wallet software or that may be transmitted to or
+ through our services by any third party (regardless of the
+ source of origination), or
+
+2. any direct damages.
+
+These limitations apply regardless of legal theory, whether based on
+tort, strict liability, breach of contract, breach of warranty, or any
+other legal theory, and whether or not we were advised of the
+possibility of such damages. Some jurisdictions do not allow the
+exclusion or limitation of liability for consequential or incidental
+damages, so the above limitation may not apply to you.
+
+
+Warranty disclaimer
+===================
+
+Our services are provided "as is" and without warranty of any kind. To
+the maximum extent permitted by law, we disclaim all representations
+and warranties, express or implied, relating to the services and
+underlying software or any content on the services, whether provided
+or owned by us or by any third party, including without limitation,
+warranties of merchantability, fitness for a particular purpose,
+title, non-infringement, freedom from computer virus, and any implied
+warranties arising from course of dealing, course of performance, or
+usage in trade, all of which are expressly disclaimed. In addition, we
+do not represent or warrant that the content accessible via the
+services is accurate, complete, available, current, free of viruses or
+other harmful components, or that the results of using the services
+will meet your requirements. Some states do not allow the disclaimer
+of implied warranties, so the foregoing disclaimers may not apply to
+you. This paragraph gives you specific legal rights and you may also
+have other legal rights that vary from state to state.
+
+
+Indemntiy
+=========
+
+To the extent permitted by applicable law, you agree to defend,
+indemnify, and hold harmless the Taler Parties from and against any
+and all claims, damages, obligations, losses, liabilities, costs or
+debt, and expenses (including, but not limited to, attorney’s fees)
+arising from: (a) your use of and access to the Services; (b) any
+feedback or submissions you provide to us concerning the Taler Wallet;
+(c) your violation of any term of this Agreement; or (d) your
+violation of any law, rule, or regulation, or the rights of any third
+party.
+
+
+Time limitation on claims
+=========================
+
+You agree that any claim you may have arising out of or related to
+your relationship with us must be filed within one year after such
+claim arises, otherwise, your claim in permanently barred.
+
+
+Governing law
+=============
+
+No matter where you’re located, the laws of Switzerland will govern
+these Terms. If any provisions of these Terms are inconsistent with
+any applicable law, those provisions will be superseded or modified
+only to the extent such provisions are inconsistent. The parties agree
+to submit to the ordinary courts in Zurich, Switzerland for exclusive
+jurisdiction of any dispute arising out of or related to your use of
+the Services or your breach of these Terms.
+
+
+Termination
+===========
In the event of termination concerning your use of our Services, your
obligations under this Agreement will still continue.
-DISCONTINUANCE OF SERVICES
-We may, in our sole discretion and without cost to you, with or without prior
-notice, and at any time, modify or discontinue, temporarily or permanently,
-any portion of our Services. We will use the Taler protocol’s provisions to
-notify Wallets if our Services are to be discontinued. It is your
-responsibility to ensure that the Taler Wallet is online at least once every
-three months to observe these notifications. We shall not be held responsible
-or liable for any loss of funds in the event that we discontinue or depreciate
-the Services and your Taler Wallet fails to transfer out the coins within a
-three months notification period.
+Discontinuance of services
+==========================
+
+We may, in our sole discretion and without cost to you, with or
+without prior notice, and at any time, modify or discontinue,
+temporarily or permanently, any portion of our Services. We will use
+the Taler protocol’s provisions to notify Wallets if our Services are
+to be discontinued. It is your responsibility to ensure that the Taler
+Wallet is online at least once every three months to observe these
+notifications. We shall not be held responsible or liable for any loss
+of funds in the event that we discontinue or depreciate the Services
+and your Taler Wallet fails to transfer out the coins within a three
+months notification period.
+
-NO WAIVER
+No waiver
+=========
-Our failure to exercise or delay in exercising any right, power, or privilege
-under this Agreement shall not operate as a waiver; nor shall any single or
-partial exercise of any right, power, or privilege preclude any other or
-further exercise thereof.
+Our failure to exercise or delay in exercising any right, power, or
+privilege under this Agreement shall not operate as a waiver; nor
+shall any single or partial exercise of any right, power, or privilege
+preclude any other or further exercise thereof.
-SEVERABILITY
-If it turns out that any part of this Agreement is invalid, void, or for any
-reason unenforceable, that term will be deemed severable and limited or
-eliminated to the minimum extent necessary.
+Severability
+============
-FORCE MAJEURE
+If it turns out that any part of this Agreement is invalid, void, or
+for any reason unenforceable, that term will be deemed severable and
+limited or eliminated to the minimum extent necessary.
+
+
+Force majeure
+=============
We shall not be held liable for any delays, failure in performance, or
-interruptions of service which result directly or indirectly from any cause or
-condition beyond our reasonable control, including but not limited to: any
-delay or failure due to any act of God, act of civil or military authorities,
-act of terrorism, civil disturbance, war, strike or other labor dispute, fire,
-interruption in telecommunications or Internet services or network provider
-services, failure of equipment and/or software, other catastrophe, or any
-other occurrence which is beyond our reasonable control and shall not affect
+interruptions of service which result directly or indirectly from any
+cause or condition beyond our reasonable control, including but not
+limited to: any delay or failure due to any act of God, act of civil
+or military authorities, act of terrorism, civil disturbance, war,
+strike or other labor dispute, fire, interruption in
+telecommunications or Internet services or network provider services,
+failure of equipment and/or software, other catastrophe, or any other
+occurrence which is beyond our reasonable control and shall not affect
the validity and enforceability of any remaining provisions.
-ASSIGNMENT
-You agree that we may assign any of our rights and/or transfer, sub-contract,
-or delegate any of our obligations under these Terms.
+Assignment
+==========
+
+You agree that we may assign any of our rights and/or transfer, sub-
+contract, or delegate any of our obligations under these Terms.
+
+
+Entire agreement
+================
-ENTIRE AGREEMENT
+This Agreement sets forth the entire understanding and agreement as to
+the subject matter hereof and supersedes any and all prior
+discussions, agreements, and understandings of any kind (including,
+without limitation, any prior versions of this Agreement) and every
+nature between us. Except as provided for above, any modification to
+this Agreement must be in writing and must be signed by both parties.
-This Agreement sets forth the entire understanding and agreement as to the
-subject matter hereof and supersedes any and all prior discussions,
-agreements, and understandings of any kind (including, without limitation, any
-prior versions of this Agreement) and every nature between us. Except as
-provided for above, any modification to this Agreement must be in writing and
-must be signed by both parties.
-QUESTIONS OR COMMENTS
+Questions or comments
+=====================
-We welcome comments, questions, concerns, or suggestions. Please send us a
-message on our contact page at legal@taler-systems.com.
+We welcome comments, questions, concerns, or suggestions. Please send
+us a message on our contact page at legal@taler-systems.com.
diff --git a/contrib/tos/en/0.xml b/contrib/tos/en/0.xml
new file mode 100644
index 00000000..45871ead
--- /dev/null
+++ b/contrib/tos/en/0.xml
@@ -0,0 +1,344 @@
+
+
+
+
+
+ Terms Of Service
+ Last Updated: 12.4.2019
+ Welcome! Taler Systems SA (“we,” “our,” or “us”) provides a payment service
+ through our Internet presence (collectively the “Services”). Before using our
+ Services, please read the Terms of Service (the “Terms” or the “Agreement”)
+ carefully.
+
+ Overview
+ This section provides a brief summary of the highlights of this
+ Agreement. Please note that when you accept this Agreement, you are accepting
+ all of the terms and conditions and not just this section. We and possibly
+ other third parties provide Internet services which interact with the Taler
+ Wallet’s self-hosted personal payment application. When using the Taler Wallet
+ to interact with our Services, you are agreeing to our Terms, so please read
+ carefully.
+
+ Highlights:
+
+
+
+ You are responsible for keeping the data in your Taler Wallet at all times
+ under your control. Any losses arising from you not being in control of
+ your private information are your problem.
+
+
+ We will try to transfer funds we hold in escrow for our users to any legal
+ recipient to the best of our ability within the limitations of the law and
+ our implementation. However, the Services offered today are highly
+ experimental and the set of recipients of funds is severely restricted.
+
+
+ For our Services, we may charge transaction fees. The specific fee structure
+ is provided based on the Taler protocol and should be shown to you when you
+ withdraw electronic coins using a Taler Wallet. You agree and understand
+ that the Taler protocol allows for the fee structure to change.
+
+
+ You agree to not intentionally overwhelm our systems with requests and
+ follow responsible disclosure if you find security issues in our services.
+
+
+ We cannot be held accountable for our Services not being available due to
+ circumstances beyond our control. If we modify or terminate our services,
+ we will try to give you the opportunity to recover your funds. However,
+ given the experimental state of the Services today, this may not be
+ possible. You are strongly advised to limit your use of the Service
+ to small-scale experiments expecting total loss of all funds.
+
+
+
+ These terms outline approved uses of our Services. The Services and these
+ Terms are still at an experimental stage. If you have any questions or
+ comments related to this Agreement, please send us a message to
+ legal@taler-systems.com. If you do not agree to this Agreement, you must not
+ use our Services.
+
+
+
+ How you accept this policy
+ By sending funds to us (to top-up your Taler Wallet), you acknowledge that you
+ have read, understood, and agreed to these Terms. We reserve the right to
+ change these Terms at any time. If you disagree with the change, we may in the
+ future offer you with an easy option to recover your unspent funds. However,
+ in the current experimental period you acknowledge that this feature is not
+ yet available, resulting in your funds being lost unless you accept the new
+ Terms. If you continue to use our Services other than to recover your unspent
+ funds, your continued use of our Services following any such change will
+ signify your acceptance to be bound by the then current Terms. Please check
+ the effective date above to determine if there have been any changes since you
+ have last reviewed these Terms.
+
+
+ Services
+ We will try to transfer funds that we hold in escrow for our users to any
+ legal recipient to the best of our ability and within the limitations of the
+ law and our implementation. However, the Services offered today are highly
+ experimental and the set of recipients of funds is severely restricted. The
+ Taler Wallet can be loaded by exchanging fiat currencies against electronic
+ coins. We are providing this exchange service. Once your Taler Wallet is
+ loaded with electronic coins they can be spent for purchases if the seller is
+ accepting Taler as a means of payment. We are not guaranteeing that any seller
+ is accepting Taler at all or a particular seller. The seller or recipient of
+ deposits of electronic coins must specify the target account, as per the
+ design of the Taler protocol. They are responsible for following the protocol
+ and specifying the correct bank account, and are solely liable for any losses
+ that may arise from specifying the wrong account. We will allow the government
+ to link wire transfers to the underlying contract hash. It is the
+ responsibility of recipients to preserve the full contracts and to pay
+ whatever taxes and charges may be applicable. Technical issues may lead to
+ situations where we are unable to make transfers at all or lead to incorrect
+ transfers that cannot be reversed. We will only refuse to execute transfers if
+ the transfers are prohibited by a competent legal authority and we are ordered
+ to do so.
+
+
+ Fees
+ You agree to pay the fees for exchanges and withdrawals completed via the
+ Taler Wallet (“Fees”) as defined by us, which we may change from time to
+ time. With the exception of wire transfer fees, Taler transaction fees are set
+ for any electronic coin at the time of withdrawal and fixed throughout the
+ validity period of the respective electronic coin. Your wallet should obtain
+ and display applicable fees when withdrawing funds. Fees for coins obtained as
+ change may differ from the fees applicable to the original coin. Wire transfer
+ fees that are independent from electronic coins may change annually. You
+ authorize us to charge or deduct applicable fees owed in connection with
+ deposits, exchanges and withdrawals following the rules of the Taler protocol.
+ We reserve the right to provide different types of rewards to users either in
+ the form of discount for our Services or in any other form at our discretion
+ and without prior notice to you.
+
+
+ Eligibility
+ To be eligible to use our Services, you must be able to form legally binding
+ contracts or have the permission of your legal guardian. By using our
+ Services, you represent and warrant that you meet all eligibility requirements
+ that we outline in these Terms.
+
+
+ Financial self-responsibility
+ You will be responsible for maintaining the availability, integrity and
+ confidentiality of the data stored in your wallet. When you setup a Taler
+ Wallet, you are strongly advised to follow the precautionary measures offered
+ by the software to minimize the chances to losse access to or control over
+ your Wallet data. We will not be liable for any loss or damage arising from
+ your failure to comply with this paragraph.
+
+
+ Copyrights and trademarks
+ The Taler Wallet is released under the terms of the GNU General Public License
+ (GNU GPL). You have the right to access, use, and share the Taler Wallet, in
+ modified or unmodified form. However, the GPL is a strong copyleft license,
+ which means that any derivative works must be distributed under the same
+ license terms as the original software. If you have any questions, you should
+ review the GNU GPL’s full terms and conditions at
+ https://www.gnu.org/licenses/gpl-3.0.en.html. “Taler” itself is a trademark
+ of Taler Systems SA. You are welcome to use the name in relation to processing
+ payments using the Taler protocol, assuming your use is compatible with an
+ official release from the GNU Project that is not older than two years.
+
+
+ Your use of our services
+ When using our Services, you agree to not take any action that intentionally
+ imposes an unreasonable load on our infrastructure. If you find security
+ problems in our Services, you agree to first report them to
+ security@taler-systems.com and grant us the right to publish your report. We
+ warrant that we will ourselves publicly disclose any issues reported within 3
+ months, and that we will not prosecute anyone reporting security issues if
+ they did not exploit the issue beyond a proof-of-concept, and followed the
+ above responsible disclosure practice.
+
+
+ Limitation of liability & disclaimer of warranties
+ You understand and agree that we have no control over, and no duty to take any
+ action regarding: Failures, disruptions, errors, or delays in processing that
+ you may experience while using our Services; The risk of failure of hardware,
+ software, and Internet connections; The risk of malicious software being
+ introduced or found in the software underlying the Taler Wallet; The risk that
+ third parties may obtain unauthorized access to information stored within your
+ Taler Wallet, including, but not limited to your Taler Wallet coins or backup
+ encryption keys. You release us from all liability related to any losses,
+ damages, or claims arising from:
+
+
+ user error such as forgotten passwords, incorrectly constructed
+ transactions;
+
+
+ server failure or data loss;
+
+
+ unauthorized access to the Taler Wallet application;
+
+
+ bugs or other errors in the Taler Wallet software; and
+
+
+ any unauthorized third party activities, including, but not limited to,
+ the use of viruses, phishing, brute forcing, or other means of attack
+ against the Taler Wallet. We make no representations concerning any
+ Third Party Content contained in or accessed through our Services.
+
+
+ Any other terms, conditions, warranties, or representations associated with
+ such content, are solely between you and such organizations and/or
+ individuals.
+
+
+ Limitation of liability
+ To the fullest extent permitted by applicable law, in no event will we or any
+ of our officers, directors, representatives, agents, servants, counsel,
+ employees, consultants, lawyers, and other personnel authorized to act,
+ acting, or purporting to act on our behalf (collectively the “Taler Parties”)
+ be liable to you under contract, tort, strict liability, negligence, or any
+ other legal or equitable theory, for:
+
+
+ any lost profits, data loss, cost of procurement of substitute goods or
+ services, or direct, indirect, incidental, special, punitive, compensatory,
+ or consequential damages of any kind whatsoever resulting from:
+
+
+
+
+
+ your use of, or conduct in connection with, our services;
+
+
+ any unauthorized use of your wallet and/or private key due to your
+ failure to maintain the confidentiality of your wallet;
+
+
+ any interruption or cessation of transmission to or from the services; or
+
+
+ any bugs, viruses, trojan horses, or the like that are found in the Taler
+ Wallet software or that may be transmitted to or through our services by
+ any third party (regardless of the source of origination), or
+
+
+
+
+
+ any direct damages.
+
+
+ These limitations apply regardless of legal theory, whether based on tort,
+ strict liability, breach of contract, breach of warranty, or any other legal
+ theory, and whether or not we were advised of the possibility of such
+ damages. Some jurisdictions do not allow the exclusion or limitation of
+ liability for consequential or incidental damages, so the above limitation may
+ not apply to you.
+
+
+ Warranty disclaimer
+ Our services are provided “as is” and without warranty of any kind. To the
+ maximum extent permitted by law, we disclaim all representations and
+ warranties, express or implied, relating to the services and underlying
+ software or any content on the services, whether provided or owned by us or by
+ any third party, including without limitation, warranties of merchantability,
+ fitness for a particular purpose, title, non-infringement, freedom from
+ computer virus, and any implied warranties arising from course of dealing,
+ course of performance, or usage in trade, all of which are expressly
+ disclaimed. In addition, we do not represent or warrant that the content
+ accessible via the services is accurate, complete, available, current, free of
+ viruses or other harmful components, or that the results of using the services
+ will meet your requirements. Some states do not allow the disclaimer of
+ implied warranties, so the foregoing disclaimers may not apply to you. This
+ paragraph gives you specific legal rights and you may also have other legal
+ rights that vary from state to state.
+
+
+ Indemntiy
+ To the extent permitted by applicable law, you agree to defend, indemnify, and
+ hold harmless the Taler Parties from and against any and all claims, damages,
+ obligations, losses, liabilities, costs or debt, and expenses (including, but
+ not limited to, attorney’s fees) arising from: (a) your use of and access to
+ the Services; (b) any feedback or submissions you provide to us concerning the
+ Taler Wallet; (c) your violation of any term of this Agreement; or (d) your
+ violation of any law, rule, or regulation, or the rights of any third party.
+
+
+ Time limitation on claims
+ You agree that any claim you may have arising out of or related to your
+ relationship with us must be filed within one year after such claim arises,
+ otherwise, your claim in permanently barred.
+
+
+ Governing law
+ No matter where you’re located, the laws of Switzerland will govern these
+ Terms. If any provisions of these Terms are inconsistent with any applicable
+ law, those provisions will be superseded or modified only to the extent such
+ provisions are inconsistent. The parties agree to submit to the ordinary
+ courts in Zurich, Switzerland for exclusive jurisdiction of any dispute
+ arising out of or related to your use of the Services or your breach of these
+ Terms.
+
+
+ Termination
+ In the event of termination concerning your use of our Services, your
+ obligations under this Agreement will still continue.
+
+
+ Discontinuance of services
+ We may, in our sole discretion and without cost to you, with or without prior
+ notice, and at any time, modify or discontinue, temporarily or permanently,
+ any portion of our Services. We will use the Taler protocol’s provisions to
+ notify Wallets if our Services are to be discontinued. It is your
+ responsibility to ensure that the Taler Wallet is online at least once every
+ three months to observe these notifications. We shall not be held responsible
+ or liable for any loss of funds in the event that we discontinue or depreciate
+ the Services and your Taler Wallet fails to transfer out the coins within a
+ three months notification period.
+
+
+ No waiver
+ Our failure to exercise or delay in exercising any right, power, or privilege
+ under this Agreement shall not operate as a waiver; nor shall any single or
+ partial exercise of any right, power, or privilege preclude any other or
+ further exercise thereof.
+
+
+ Severability
+ If it turns out that any part of this Agreement is invalid, void, or for any
+ reason unenforceable, that term will be deemed severable and limited or
+ eliminated to the minimum extent necessary.
+
+
+ Force majeure
+ We shall not be held liable for any delays, failure in performance, or
+ interruptions of service which result directly or indirectly from any cause or
+ condition beyond our reasonable control, including but not limited to: any
+ delay or failure due to any act of God, act of civil or military authorities,
+ act of terrorism, civil disturbance, war, strike or other labor dispute, fire,
+ interruption in telecommunications or Internet services or network provider
+ services, failure of equipment and/or software, other catastrophe, or any
+ other occurrence which is beyond our reasonable control and shall not affect
+ the validity and enforceability of any remaining provisions.
+
+
+ Assignment
+ You agree that we may assign any of our rights and/or transfer, sub-contract,
+ or delegate any of our obligations under these Terms.
+
+
+ Entire agreement
+ This Agreement sets forth the entire understanding and agreement as to the
+ subject matter hereof and supersedes any and all prior discussions,
+ agreements, and understandings of any kind (including, without limitation, any
+ prior versions of this Agreement) and every nature between us. Except as
+ provided for above, any modification to this Agreement must be in writing and
+ must be signed by both parties.
+
+
+ Questions or comments
+ We welcome comments, questions, concerns, or suggestions. Please send us a
+ message on our contact page at legal@taler-systems.com.
+
+
+
diff --git a/contrib/tos/locale/de/LC_MESSAGES/tos.po b/contrib/tos/locale/de/LC_MESSAGES/tos.po
new file mode 100644
index 00000000..4644a5c8
--- /dev/null
+++ b/contrib/tos/locale/de/LC_MESSAGES/tos.po
@@ -0,0 +1,514 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) 2014-2020 Taler Systems SA (GPLv3+ or GFDL 1.3+)
+# This file is distributed under the same license as the tos package.
+# FIRST AUTHOR , 2020.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: tos 0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2020-02-07 00:35+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: LANGUAGE \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.6.0\n"
+
+#: ../../tos.rst:2
+msgid "Terms Of Service"
+msgstr ""
+
+#: ../../tos.rst:4
+msgid "Last Updated: 12.4.2019"
+msgstr ""
+
+#: ../../tos.rst:6
+msgid ""
+"Welcome! Taler Systems SA (“we,” “our,” or “us”) provides a payment "
+"service through our Internet presence (collectively the “Services”). "
+"Before using our Services, please read the Terms of Service (the “Terms” "
+"or the “Agreement”) carefully."
+msgstr ""
+
+#: ../../tos.rst:12
+msgid "Overview"
+msgstr ""
+
+#: ../../tos.rst:14
+msgid ""
+"This section provides a brief summary of the highlights of this "
+"Agreement. Please note that when you accept this Agreement, you are "
+"accepting all of the terms and conditions and not just this section. We "
+"and possibly other third parties provide Internet services which interact"
+" with the Taler Wallet’s self-hosted personal payment application. When "
+"using the Taler Wallet to interact with our Services, you are agreeing to"
+" our Terms, so please read carefully."
+msgstr ""
+
+#: ../../tos.rst:23
+msgid "Highlights:"
+msgstr ""
+
+#: ../../tos.rst:25
+msgid ""
+"You are responsible for keeping the data in your Taler Wallet at all "
+"times under your control. Any losses arising from you not being in "
+"control of your private information are your problem."
+msgstr ""
+
+#: ../../tos.rst:28
+msgid ""
+"We will try to transfer funds we hold in escrow for our users to any "
+"legal recipient to the best of our ability within the limitations of the "
+"law and our implementation. However, the Services offered today are "
+"highly experimental and the set of recipients of funds is severely "
+"restricted."
+msgstr ""
+
+#: ../../tos.rst:32
+msgid ""
+"For our Services, we may charge transaction fees. The specific fee "
+"structure is provided based on the Taler protocol and should be shown to "
+"you when you withdraw electronic coins using a Taler Wallet. You agree "
+"and understand that the Taler protocol allows for the fee structure to "
+"change."
+msgstr ""
+
+#: ../../tos.rst:36
+msgid ""
+"You agree to not intentionally overwhelm our systems with requests and "
+"follow responsible disclosure if you find security issues in our "
+"services."
+msgstr ""
+
+#: ../../tos.rst:38
+msgid ""
+"We cannot be held accountable for our Services not being available due to"
+" circumstances beyond our control. If we modify or terminate our "
+"services, we will try to give you the opportunity to recover your funds. "
+"However, given the experimental state of the Services today, this may not"
+" be possible. You are strongly advised to limit your use of the Service "
+"to small-scale experiments expecting total loss of all funds."
+msgstr ""
+
+#: ../../tos.rst:45
+msgid ""
+"These terms outline approved uses of our Services. The Services and these"
+" Terms are still at an experimental stage. If you have any questions or "
+"comments related to this Agreement, please send us a message to legal"
+"@taler-systems.com. If you do not agree to this Agreement, you must not "
+"use our Services."
+msgstr ""
+
+#: ../../tos.rst:52
+msgid "How you accept this policy"
+msgstr ""
+
+#: ../../tos.rst:54
+msgid ""
+"By sending funds to us (to top-up your Taler Wallet), you acknowledge "
+"that you have read, understood, and agreed to these Terms. We reserve the"
+" right to change these Terms at any time. If you disagree with the "
+"change, we may in the future offer you with an easy option to recover "
+"your unspent funds. However, in the current experimental period you "
+"acknowledge that this feature is not yet available, resulting in your "
+"funds being lost unless you accept the new Terms. If you continue to use "
+"our Services other than to recover your unspent funds, your continued use"
+" of our Services following any such change will signify your acceptance "
+"to be bound by the then current Terms. Please check the effective date "
+"above to determine if there have been any changes since you have last "
+"reviewed these Terms."
+msgstr ""
+
+#: ../../tos.rst:67
+msgid "Services"
+msgstr ""
+
+#: ../../tos.rst:69
+msgid ""
+"We will try to transfer funds that we hold in escrow for our users to any"
+" legal recipient to the best of our ability and within the limitations of"
+" the law and our implementation. However, the Services offered today are "
+"highly experimental and the set of recipients of funds is severely "
+"restricted. The Taler Wallet can be loaded by exchanging fiat currencies"
+" against electronic coins. We are providing this exchange service. Once "
+"your Taler Wallet is loaded with electronic coins they can be spent for "
+"purchases if the seller is accepting Taler as a means of payment. We are "
+"not guaranteeing that any seller is accepting Taler at all or a "
+"particular seller. The seller or recipient of deposits of electronic "
+"coins must specify the target account, as per the design of the Taler "
+"protocol. They are responsible for following the protocol and specifying "
+"the correct bank account, and are solely liable for any losses that may "
+"arise from specifying the wrong account. We will allow the government to "
+"link wire transfers to the underlying contract hash. It is the "
+"responsibility of recipients to preserve the full contracts and to pay "
+"whatever taxes and charges may be applicable. Technical issues may lead "
+"to situations where we are unable to make transfers at all or lead to "
+"incorrect transfers that cannot be reversed. We will only refuse to "
+"execute transfers if the transfers are prohibited by a competent legal "
+"authority and we are ordered to do so."
+msgstr ""
+
+#: ../../tos.rst:91
+msgid "Fees"
+msgstr ""
+
+#: ../../tos.rst:93
+msgid ""
+"You agree to pay the fees for exchanges and withdrawals completed via the"
+" Taler Wallet (\"Fees\") as defined by us, which we may change from time "
+"to time. With the exception of wire transfer fees, Taler transaction fees"
+" are set for any electronic coin at the time of withdrawal and fixed "
+"throughout the validity period of the respective electronic coin. Your "
+"wallet should obtain and display applicable fees when withdrawing funds. "
+"Fees for coins obtained as change may differ from the fees applicable to "
+"the original coin. Wire transfer fees that are independent from "
+"electronic coins may change annually. You authorize us to charge or "
+"deduct applicable fees owed in connection with deposits, exchanges and "
+"withdrawals following the rules of the Taler protocol. We reserve the "
+"right to provide different types of rewards to users either in the form "
+"of discount for our Services or in any other form at our discretion and "
+"without prior notice to you."
+msgstr ""
+
+#: ../../tos.rst:108
+msgid "Eligibility"
+msgstr ""
+
+#: ../../tos.rst:110
+msgid ""
+"To be eligible to use our Services, you must be able to form legally "
+"binding contracts or have the permission of your legal guardian. By using"
+" our Services, you represent and warrant that you meet all eligibility "
+"requirements that we outline in these Terms."
+msgstr ""
+
+#: ../../tos.rst:116
+msgid "Financial self-responsibility"
+msgstr ""
+
+#: ../../tos.rst:118
+msgid ""
+"You will be responsible for maintaining the availability, integrity and "
+"confidentiality of the data stored in your wallet. When you setup a Taler"
+" Wallet, you are strongly advised to follow the precautionary measures "
+"offered by the software to minimize the chances to losse access to or "
+"control over your Wallet data. We will not be liable for any loss or "
+"damage arising from your failure to comply with this paragraph."
+msgstr ""
+
+#: ../../tos.rst:126
+msgid "Copyrights and trademarks"
+msgstr ""
+
+#: ../../tos.rst:128
+msgid ""
+"The Taler Wallet is released under the terms of the GNU General Public "
+"License (GNU GPL). You have the right to access, use, and share the Taler"
+" Wallet, in modified or unmodified form. However, the GPL is a strong "
+"copyleft license, which means that any derivative works must be "
+"distributed under the same license terms as the original software. If you"
+" have any questions, you should review the GNU GPL’s full terms and "
+"conditions at https://www.gnu.org/licenses/gpl-3.0.en.html. “Taler” "
+"itself is a trademark of Taler Systems SA. You are welcome to use the "
+"name in relation to processing payments using the Taler protocol, "
+"assuming your use is compatible with an official release from the GNU "
+"Project that is not older than two years."
+msgstr ""
+
+#: ../../tos.rst:140
+msgid "Your use of our services"
+msgstr ""
+
+#: ../../tos.rst:142
+msgid ""
+"When using our Services, you agree to not take any action that "
+"intentionally imposes an unreasonable load on our infrastructure. If you "
+"find security problems in our Services, you agree to first report them to"
+" security@taler-systems.com and grant us the right to publish your "
+"report. We warrant that we will ourselves publicly disclose any issues "
+"reported within 3 months, and that we will not prosecute anyone reporting"
+" security issues if they did not exploit the issue beyond a proof-of-"
+"concept, and followed the above responsible disclosure practice."
+msgstr ""
+
+#: ../../tos.rst:152
+msgid "Limitation of liability & disclaimer of warranties"
+msgstr ""
+
+#: ../../tos.rst:154
+msgid ""
+"You understand and agree that we have no control over, and no duty to "
+"take any action regarding: Failures, disruptions, errors, or delays in "
+"processing that you may experience while using our Services; The risk of "
+"failure of hardware, software, and Internet connections; The risk of "
+"malicious software being introduced or found in the software underlying "
+"the Taler Wallet; The risk that third parties may obtain unauthorized "
+"access to information stored within your Taler Wallet, including, but not"
+" limited to your Taler Wallet coins or backup encryption keys. You "
+"release us from all liability related to any losses, damages, or claims "
+"arising from:"
+msgstr ""
+
+#: ../../tos.rst:164
+msgid ""
+"user error such as forgotten passwords, incorrectly constructed "
+"transactions;"
+msgstr ""
+
+#: ../../tos.rst:166
+msgid "server failure or data loss;"
+msgstr ""
+
+#: ../../tos.rst:167
+msgid "unauthorized access to the Taler Wallet application;"
+msgstr ""
+
+#: ../../tos.rst:168
+msgid "bugs or other errors in the Taler Wallet software; and"
+msgstr ""
+
+#: ../../tos.rst:169
+msgid ""
+"any unauthorized third party activities, including, but not limited to, "
+"the use of viruses, phishing, brute forcing, or other means of attack "
+"against the Taler Wallet. We make no representations concerning any Third"
+" Party Content contained in or accessed through our Services."
+msgstr ""
+
+#: ../../tos.rst:174
+msgid ""
+"Any other terms, conditions, warranties, or representations associated "
+"with such content, are solely between you and such organizations and/or "
+"individuals."
+msgstr ""
+
+#: ../../tos.rst:179
+msgid "Limitation of liability"
+msgstr ""
+
+#: ../../tos.rst:181
+msgid ""
+"To the fullest extent permitted by applicable law, in no event will we or"
+" any of our officers, directors, representatives, agents, servants, "
+"counsel, employees, consultants, lawyers, and other personnel authorized "
+"to act, acting, or purporting to act on our behalf (collectively the "
+"“Taler Parties”) be liable to you under contract, tort, strict liability,"
+" negligence, or any other legal or equitable theory, for:"
+msgstr ""
+
+#: ../../tos.rst:188
+msgid ""
+"any lost profits, data loss, cost of procurement of substitute goods or "
+"services, or direct, indirect, incidental, special, punitive, "
+"compensatory, or consequential damages of any kind whatsoever resulting "
+"from:"
+msgstr ""
+
+#: ../../tos.rst:192
+msgid "your use of, or conduct in connection with, our services;"
+msgstr ""
+
+#: ../../tos.rst:193
+msgid ""
+"any unauthorized use of your wallet and/or private key due to your "
+"failure to maintain the confidentiality of your wallet;"
+msgstr ""
+
+#: ../../tos.rst:195
+msgid "any interruption or cessation of transmission to or from the services; or"
+msgstr ""
+
+#: ../../tos.rst:196
+msgid ""
+"any bugs, viruses, trojan horses, or the like that are found in the Taler"
+" Wallet software or that may be transmitted to or through our services by"
+" any third party (regardless of the source of origination), or"
+msgstr ""
+
+#: ../../tos.rst:200
+msgid "any direct damages."
+msgstr ""
+
+#: ../../tos.rst:202
+msgid ""
+"These limitations apply regardless of legal theory, whether based on "
+"tort, strict liability, breach of contract, breach of warranty, or any "
+"other legal theory, and whether or not we were advised of the possibility"
+" of such damages. Some jurisdictions do not allow the exclusion or "
+"limitation of liability for consequential or incidental damages, so the "
+"above limitation may not apply to you."
+msgstr ""
+
+#: ../../tos.rst:210
+msgid "Warranty disclaimer"
+msgstr ""
+
+#: ../../tos.rst:212
+msgid ""
+"Our services are provided \"as is\" and without warranty of any kind. To "
+"the maximum extent permitted by law, we disclaim all representations and "
+"warranties, express or implied, relating to the services and underlying "
+"software or any content on the services, whether provided or owned by us "
+"or by any third party, including without limitation, warranties of "
+"merchantability, fitness for a particular purpose, title, non-"
+"infringement, freedom from computer virus, and any implied warranties "
+"arising from course of dealing, course of performance, or usage in trade,"
+" all of which are expressly disclaimed. In addition, we do not represent "
+"or warrant that the content accessible via the services is accurate, "
+"complete, available, current, free of viruses or other harmful "
+"components, or that the results of using the services will meet your "
+"requirements. Some states do not allow the disclaimer of implied "
+"warranties, so the foregoing disclaimers may not apply to you. This "
+"paragraph gives you specific legal rights and you may also have other "
+"legal rights that vary from state to state."
+msgstr ""
+
+#: ../../tos.rst:229
+msgid "Indemntiy"
+msgstr ""
+
+#: ../../tos.rst:231
+msgid ""
+"To the extent permitted by applicable law, you agree to defend, "
+"indemnify, and hold harmless the Taler Parties from and against any and "
+"all claims, damages, obligations, losses, liabilities, costs or debt, and"
+" expenses (including, but not limited to, attorney’s fees) arising from: "
+"(a) your use of and access to the Services; (b) any feedback or "
+"submissions you provide to us concerning the Taler Wallet; (c) your "
+"violation of any term of this Agreement; or (d) your violation of any "
+"law, rule, or regulation, or the rights of any third party."
+msgstr ""
+
+#: ../../tos.rst:240
+msgid "Time limitation on claims"
+msgstr ""
+
+#: ../../tos.rst:242
+msgid ""
+"You agree that any claim you may have arising out of or related to your "
+"relationship with us must be filed within one year after such claim "
+"arises, otherwise, your claim in permanently barred."
+msgstr ""
+
+#: ../../tos.rst:247
+msgid "Governing law"
+msgstr ""
+
+#: ../../tos.rst:249
+msgid ""
+"No matter where you’re located, the laws of Switzerland will govern these"
+" Terms. If any provisions of these Terms are inconsistent with any "
+"applicable law, those provisions will be superseded or modified only to "
+"the extent such provisions are inconsistent. The parties agree to submit "
+"to the ordinary courts in Zurich, Switzerland for exclusive jurisdiction "
+"of any dispute arising out of or related to your use of the Services or "
+"your breach of these Terms."
+msgstr ""
+
+#: ../../tos.rst:258
+msgid "Termination"
+msgstr ""
+
+#: ../../tos.rst:260
+msgid ""
+"In the event of termination concerning your use of our Services, your "
+"obligations under this Agreement will still continue."
+msgstr ""
+
+#: ../../tos.rst:264
+msgid "Discontinuance of services"
+msgstr ""
+
+#: ../../tos.rst:266
+msgid ""
+"We may, in our sole discretion and without cost to you, with or without "
+"prior notice, and at any time, modify or discontinue, temporarily or "
+"permanently, any portion of our Services. We will use the Taler "
+"protocol’s provisions to notify Wallets if our Services are to be "
+"discontinued. It is your responsibility to ensure that the Taler Wallet "
+"is online at least once every three months to observe these "
+"notifications. We shall not be held responsible or liable for any loss of"
+" funds in the event that we discontinue or depreciate the Services and "
+"your Taler Wallet fails to transfer out the coins within a three months "
+"notification period."
+msgstr ""
+
+#: ../../tos.rst:277
+msgid "No waiver"
+msgstr ""
+
+#: ../../tos.rst:279
+msgid ""
+"Our failure to exercise or delay in exercising any right, power, or "
+"privilege under this Agreement shall not operate as a waiver; nor shall "
+"any single or partial exercise of any right, power, or privilege preclude"
+" any other or further exercise thereof."
+msgstr ""
+
+#: ../../tos.rst:285
+msgid "Severability"
+msgstr ""
+
+#: ../../tos.rst:287
+msgid ""
+"If it turns out that any part of this Agreement is invalid, void, or for "
+"any reason unenforceable, that term will be deemed severable and limited "
+"or eliminated to the minimum extent necessary."
+msgstr ""
+
+#: ../../tos.rst:292
+msgid "Force majeure"
+msgstr ""
+
+#: ../../tos.rst:294
+msgid ""
+"We shall not be held liable for any delays, failure in performance, or "
+"interruptions of service which result directly or indirectly from any "
+"cause or condition beyond our reasonable control, including but not "
+"limited to: any delay or failure due to any act of God, act of civil or "
+"military authorities, act of terrorism, civil disturbance, war, strike or"
+" other labor dispute, fire, interruption in telecommunications or "
+"Internet services or network provider services, failure of equipment "
+"and/or software, other catastrophe, or any other occurrence which is "
+"beyond our reasonable control and shall not affect the validity and "
+"enforceability of any remaining provisions."
+msgstr ""
+
+#: ../../tos.rst:305
+msgid "Assignment"
+msgstr ""
+
+#: ../../tos.rst:307
+msgid ""
+"You agree that we may assign any of our rights and/or transfer, sub-"
+"contract, or delegate any of our obligations under these Terms."
+msgstr ""
+
+#: ../../tos.rst:311
+msgid "Entire agreement"
+msgstr ""
+
+#: ../../tos.rst:313
+msgid ""
+"This Agreement sets forth the entire understanding and agreement as to "
+"the subject matter hereof and supersedes any and all prior discussions, "
+"agreements, and understandings of any kind (including, without "
+"limitation, any prior versions of this Agreement) and every nature "
+"between us. Except as provided for above, any modification to this "
+"Agreement must be in writing and must be signed by both parties."
+msgstr ""
+
+#: ../../tos.rst:321
+msgid "Questions or comments"
+msgstr ""
+
+#: ../../tos.rst:323
+msgid ""
+"We welcome comments, questions, concerns, or suggestions. Please send us "
+"a message on our contact page at legal@taler-systems.com."
+msgstr ""
+
diff --git a/contrib/tos/tos.rst b/contrib/tos/tos.rst
new file mode 100644
index 00000000..aff01001
--- /dev/null
+++ b/contrib/tos/tos.rst
@@ -0,0 +1,324 @@
+Terms Of Service
+================
+
+Last Updated: 12.4.2019
+
+Welcome! Taler Systems SA (“we,” “our,” or “us”) provides a payment service
+through our Internet presence (collectively the “Services”). Before using our
+Services, please read the Terms of Service (the “Terms” or the “Agreement”)
+carefully.
+
+Overview
+--------
+
+This section provides a brief summary of the highlights of this
+Agreement. Please note that when you accept this Agreement, you are accepting
+all of the terms and conditions and not just this section. We and possibly
+other third parties provide Internet services which interact with the Taler
+Wallet’s self-hosted personal payment application. When using the Taler Wallet
+to interact with our Services, you are agreeing to our Terms, so please read
+carefully.
+
+Highlights:
+~~~~~~~~~~~
+
+ • You are responsible for keeping the data in your Taler Wallet at all times
+ under your control. Any losses arising from you not being in control of
+ your private information are your problem.
+ • We will try to transfer funds we hold in escrow for our users to any legal
+ recipient to the best of our ability within the limitations of the law and
+ our implementation. However, the Services offered today are highly
+ experimental and the set of recipients of funds is severely restricted.
+ • For our Services, we may charge transaction fees. The specific fee structure
+ is provided based on the Taler protocol and should be shown to you when you
+ withdraw electronic coins using a Taler Wallet. You agree and understand
+ that the Taler protocol allows for the fee structure to change.
+ • You agree to not intentionally overwhelm our systems with requests and
+ follow responsible disclosure if you find security issues in our services.
+ • We cannot be held accountable for our Services not being available due to
+ circumstances beyond our control. If we modify or terminate our services,
+ we will try to give you the opportunity to recover your funds. However,
+ given the experimental state of the Services today, this may not be
+ possible. You are strongly advised to limit your use of the Service
+ to small-scale experiments expecting total loss of all funds.
+
+These terms outline approved uses of our Services. The Services and these
+Terms are still at an experimental stage. If you have any questions or
+comments related to this Agreement, please send us a message to
+legal@taler-systems.com. If you do not agree to this Agreement, you must not
+use our Services.
+
+How you accept this policy
+--------------------------
+
+By sending funds to us (to top-up your Taler Wallet), you acknowledge that you
+have read, understood, and agreed to these Terms. We reserve the right to
+change these Terms at any time. If you disagree with the change, we may in the
+future offer you with an easy option to recover your unspent funds. However,
+in the current experimental period you acknowledge that this feature is not
+yet available, resulting in your funds being lost unless you accept the new
+Terms. If you continue to use our Services other than to recover your unspent
+funds, your continued use of our Services following any such change will
+signify your acceptance to be bound by the then current Terms. Please check
+the effective date above to determine if there have been any changes since you
+have last reviewed these Terms.
+
+Services
+--------
+
+We will try to transfer funds that we hold in escrow for our users to any
+legal recipient to the best of our ability and within the limitations of the
+law and our implementation. However, the Services offered today are highly
+experimental and the set of recipients of funds is severely restricted. The
+Taler Wallet can be loaded by exchanging fiat currencies against electronic
+coins. We are providing this exchange service. Once your Taler Wallet is
+loaded with electronic coins they can be spent for purchases if the seller is
+accepting Taler as a means of payment. We are not guaranteeing that any seller
+is accepting Taler at all or a particular seller. The seller or recipient of
+deposits of electronic coins must specify the target account, as per the
+design of the Taler protocol. They are responsible for following the protocol
+and specifying the correct bank account, and are solely liable for any losses
+that may arise from specifying the wrong account. We will allow the government
+to link wire transfers to the underlying contract hash. It is the
+responsibility of recipients to preserve the full contracts and to pay
+whatever taxes and charges may be applicable. Technical issues may lead to
+situations where we are unable to make transfers at all or lead to incorrect
+transfers that cannot be reversed. We will only refuse to execute transfers if
+the transfers are prohibited by a competent legal authority and we are ordered
+to do so.
+
+Fees
+----
+
+You agree to pay the fees for exchanges and withdrawals completed via the
+Taler Wallet ("Fees") as defined by us, which we may change from time to
+time. With the exception of wire transfer fees, Taler transaction fees are set
+for any electronic coin at the time of withdrawal and fixed throughout the
+validity period of the respective electronic coin. Your wallet should obtain
+and display applicable fees when withdrawing funds. Fees for coins obtained as
+change may differ from the fees applicable to the original coin. Wire transfer
+fees that are independent from electronic coins may change annually. You
+authorize us to charge or deduct applicable fees owed in connection with
+deposits, exchanges and withdrawals following the rules of the Taler protocol.
+We reserve the right to provide different types of rewards to users either in
+the form of discount for our Services or in any other form at our discretion
+and without prior notice to you.
+
+Eligibility
+-----------
+
+To be eligible to use our Services, you must be able to form legally binding
+contracts or have the permission of your legal guardian. By using our
+Services, you represent and warrant that you meet all eligibility requirements
+that we outline in these Terms.
+
+Financial self-responsibility
+-----------------------------
+
+You will be responsible for maintaining the availability, integrity and
+confidentiality of the data stored in your wallet. When you setup a Taler
+Wallet, you are strongly advised to follow the precautionary measures offered
+by the software to minimize the chances to losse access to or control over
+your Wallet data. We will not be liable for any loss or damage arising from
+your failure to comply with this paragraph.
+
+Copyrights and trademarks
+-------------------------
+
+The Taler Wallet is released under the terms of the GNU General Public License
+(GNU GPL). You have the right to access, use, and share the Taler Wallet, in
+modified or unmodified form. However, the GPL is a strong copyleft license,
+which means that any derivative works must be distributed under the same
+license terms as the original software. If you have any questions, you should
+review the GNU GPL’s full terms and conditions at
+https://www.gnu.org/licenses/gpl-3.0.en.html. “Taler” itself is a trademark
+of Taler Systems SA. You are welcome to use the name in relation to processing
+payments using the Taler protocol, assuming your use is compatible with an
+official release from the GNU Project that is not older than two years.
+
+Your use of our services
+------------------------
+
+When using our Services, you agree to not take any action that intentionally
+imposes an unreasonable load on our infrastructure. If you find security
+problems in our Services, you agree to first report them to
+security@taler-systems.com and grant us the right to publish your report. We
+warrant that we will ourselves publicly disclose any issues reported within 3
+months, and that we will not prosecute anyone reporting security issues if
+they did not exploit the issue beyond a proof-of-concept, and followed the
+above responsible disclosure practice.
+
+Limitation of liability & disclaimer of warranties
+--------------------------------------------------
+
+You understand and agree that we have no control over, and no duty to take any
+action regarding: Failures, disruptions, errors, or delays in processing that
+you may experience while using our Services; The risk of failure of hardware,
+software, and Internet connections; The risk of malicious software being
+introduced or found in the software underlying the Taler Wallet; The risk that
+third parties may obtain unauthorized access to information stored within your
+Taler Wallet, including, but not limited to your Taler Wallet coins or backup
+encryption keys. You release us from all liability related to any losses,
+damages, or claims arising from:
+
+(a) user error such as forgotten passwords, incorrectly constructed
+ transactions;
+(b) server failure or data loss;
+(c) unauthorized access to the Taler Wallet application;
+(d) bugs or other errors in the Taler Wallet software; and
+(e) any unauthorized third party activities, including, but not limited to,
+ the use of viruses, phishing, brute forcing, or other means of attack
+ against the Taler Wallet. We make no representations concerning any
+ Third Party Content contained in or accessed through our Services.
+
+Any other terms, conditions, warranties, or representations associated with
+such content, are solely between you and such organizations and/or
+individuals.
+
+Limitation of liability
+-----------------------
+
+To the fullest extent permitted by applicable law, in no event will we or any
+of our officers, directors, representatives, agents, servants, counsel,
+employees, consultants, lawyers, and other personnel authorized to act,
+acting, or purporting to act on our behalf (collectively the “Taler Parties”)
+be liable to you under contract, tort, strict liability, negligence, or any
+other legal or equitable theory, for:
+
+(a) any lost profits, data loss, cost of procurement of substitute goods or
+ services, or direct, indirect, incidental, special, punitive, compensatory,
+ or consequential damages of any kind whatsoever resulting from:
+
+ (i) your use of, or conduct in connection with, our services;
+ (ii) any unauthorized use of your wallet and/or private key due to your
+ failure to maintain the confidentiality of your wallet;
+ (iii) any interruption or cessation of transmission to or from the services; or
+ (iv) any bugs, viruses, trojan horses, or the like that are found in the Taler
+ Wallet software or that may be transmitted to or through our services by
+ any third party (regardless of the source of origination), or
+
+(b) any direct damages.
+
+These limitations apply regardless of legal theory, whether based on tort,
+strict liability, breach of contract, breach of warranty, or any other legal
+theory, and whether or not we were advised of the possibility of such
+damages. Some jurisdictions do not allow the exclusion or limitation of
+liability for consequential or incidental damages, so the above limitation may
+not apply to you.
+
+Warranty disclaimer
+-------------------
+
+Our services are provided "as is" and without warranty of any kind. To the
+maximum extent permitted by law, we disclaim all representations and
+warranties, express or implied, relating to the services and underlying
+software or any content on the services, whether provided or owned by us or by
+any third party, including without limitation, warranties of merchantability,
+fitness for a particular purpose, title, non-infringement, freedom from
+computer virus, and any implied warranties arising from course of dealing,
+course of performance, or usage in trade, all of which are expressly
+disclaimed. In addition, we do not represent or warrant that the content
+accessible via the services is accurate, complete, available, current, free of
+viruses or other harmful components, or that the results of using the services
+will meet your requirements. Some states do not allow the disclaimer of
+implied warranties, so the foregoing disclaimers may not apply to you. This
+paragraph gives you specific legal rights and you may also have other legal
+rights that vary from state to state.
+
+Indemntiy
+---------
+
+To the extent permitted by applicable law, you agree to defend, indemnify, and
+hold harmless the Taler Parties from and against any and all claims, damages,
+obligations, losses, liabilities, costs or debt, and expenses (including, but
+not limited to, attorney’s fees) arising from: (a) your use of and access to
+the Services; (b) any feedback or submissions you provide to us concerning the
+Taler Wallet; (c) your violation of any term of this Agreement; or (d) your
+violation of any law, rule, or regulation, or the rights of any third party.
+
+Time limitation on claims
+-------------------------
+
+You agree that any claim you may have arising out of or related to your
+relationship with us must be filed within one year after such claim arises,
+otherwise, your claim in permanently barred.
+
+Governing law
+-------------
+
+No matter where you’re located, the laws of Switzerland will govern these
+Terms. If any provisions of these Terms are inconsistent with any applicable
+law, those provisions will be superseded or modified only to the extent such
+provisions are inconsistent. The parties agree to submit to the ordinary
+courts in Zurich, Switzerland for exclusive jurisdiction of any dispute
+arising out of or related to your use of the Services or your breach of these
+Terms.
+
+Termination
+-----------
+
+In the event of termination concerning your use of our Services, your
+obligations under this Agreement will still continue.
+
+Discontinuance of services
+--------------------------
+
+We may, in our sole discretion and without cost to you, with or without prior
+notice, and at any time, modify or discontinue, temporarily or permanently,
+any portion of our Services. We will use the Taler protocol’s provisions to
+notify Wallets if our Services are to be discontinued. It is your
+responsibility to ensure that the Taler Wallet is online at least once every
+three months to observe these notifications. We shall not be held responsible
+or liable for any loss of funds in the event that we discontinue or depreciate
+the Services and your Taler Wallet fails to transfer out the coins within a
+three months notification period.
+
+No waiver
+---------
+
+Our failure to exercise or delay in exercising any right, power, or privilege
+under this Agreement shall not operate as a waiver; nor shall any single or
+partial exercise of any right, power, or privilege preclude any other or
+further exercise thereof.
+
+Severability
+------------
+
+If it turns out that any part of this Agreement is invalid, void, or for any
+reason unenforceable, that term will be deemed severable and limited or
+eliminated to the minimum extent necessary.
+
+Force majeure
+-------------
+
+We shall not be held liable for any delays, failure in performance, or
+interruptions of service which result directly or indirectly from any cause or
+condition beyond our reasonable control, including but not limited to: any
+delay or failure due to any act of God, act of civil or military authorities,
+act of terrorism, civil disturbance, war, strike or other labor dispute, fire,
+interruption in telecommunications or Internet services or network provider
+services, failure of equipment and/or software, other catastrophe, or any
+other occurrence which is beyond our reasonable control and shall not affect
+the validity and enforceability of any remaining provisions.
+
+Assignment
+----------
+
+You agree that we may assign any of our rights and/or transfer, sub-contract,
+or delegate any of our obligations under these Terms.
+
+Entire agreement
+----------------
+
+This Agreement sets forth the entire understanding and agreement as to the
+subject matter hereof and supersedes any and all prior discussions,
+agreements, and understandings of any kind (including, without limitation, any
+prior versions of this Agreement) and every nature between us. Except as
+provided for above, any modification to this Agreement must be in writing and
+must be signed by both parties.
+
+Questions or comments
+---------------------
+
+We welcome comments, questions, concerns, or suggestions. Please send us a
+message on our contact page at legal@taler-systems.com.
diff --git a/contrib/update-tos.sh b/contrib/update-tos.sh
new file mode 100755
index 00000000..47d3af77
--- /dev/null
+++ b/contrib/update-tos.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+# This file is in the public domain
+
+# Should be called with the list of languages to generate, i.e.
+# $ ./update-tos.sh en de fr it
+
+# Error checking on
+set -eu
+echo "Generating TOS for ETag $VERSION"
+
+rm -f sphinx.log sphinx.err
+# We process inputs using Makefile in tos/ directory
+cd tos
+for l in $@
+do
+ mkdir -p $l
+ echo Generating TOS for language $l
+ # 'f' is for the supported formats, note that the 'make' target
+ # MUST match the file extension.
+ for f in html txt pdf epub xml
+ do
+ rm -rf _build
+ echo " Generating format $f"
+ make -e SPHINXOPTS="-D language='$l'" $f >>sphinx.log 2>>sphinx.err < /dev/null
+ mv _build/$f/tos.$f $l/${VERSION}.$f
+ done
+done
+cd ..
--
cgit v1.2.3
From f1cbc109f7cb6908469f1b8de5a10accff95244e Mon Sep 17 00:00:00 2001
From: Christian Grothoff
Date: Fri, 7 Feb 2020 00:54:01 +0100
Subject: add proper i18n for pp
---
configure.ac | 1 -
contrib/Makefile.am | 19 +-
contrib/pp/.gitignore | 3 +
contrib/pp/Makefile.am | 11 -
contrib/pp/README | 58 +++++
contrib/pp/conf.py | 282 ++++++++++++++++++++++++
contrib/pp/en/0.docx | Bin 19110 -> 0 bytes
contrib/pp/en/0.epub | Bin 0 -> 13772 bytes
contrib/pp/en/0.html | 387 +++++++++++++++------------------
contrib/pp/en/0.pdf | Bin 0 -> 81244 bytes
contrib/pp/en/0.txt | 190 ++++++++++++----
contrib/pp/en/0.xml | 167 ++++++++++++++
contrib/pp/locale/de/LC_MESSAGES/pp.po | 283 ++++++++++++++++++++++++
contrib/pp/pp.rst | 176 +++++++++++++++
contrib/update-pp.sh | 28 +++
15 files changed, 1335 insertions(+), 270 deletions(-)
create mode 100644 contrib/pp/.gitignore
delete mode 100644 contrib/pp/Makefile.am
create mode 100644 contrib/pp/README
create mode 100644 contrib/pp/conf.py
delete mode 100644 contrib/pp/en/0.docx
create mode 100644 contrib/pp/en/0.epub
create mode 100644 contrib/pp/en/0.pdf
create mode 100644 contrib/pp/en/0.xml
create mode 100644 contrib/pp/locale/de/LC_MESSAGES/pp.po
create mode 100644 contrib/pp/pp.rst
create mode 100755 contrib/update-pp.sh
diff --git a/configure.ac b/configure.ac
index 8b58bef0..58a20920 100644
--- a/configure.ac
+++ b/configure.ac
@@ -474,7 +474,6 @@ AM_CONDITIONAL([HAVE_TWISTER], [false])
AC_CONFIG_FILES([Makefile
contrib/Makefile
- contrib/pp/Makefile
doc/Makefile
doc/doxygen/Makefile
src/Makefile
diff --git a/contrib/Makefile.am b/contrib/Makefile.am
index 5a165d1f..eb4ad312 100644
--- a/contrib/Makefile.am
+++ b/contrib/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = . pp
+SUBDIRS = .
# English (en)
tosendir=$(pkgdatadir)/tos/en
@@ -13,6 +13,13 @@ tosen_DATA = \
tos/en/0.xml \
tos/en/0.html
+ppen_DATA = \
+ pp/en/0.txt \
+ pp/en/0.pdf \
+ pp/en/0.epub \
+ pp/en/0.xml \
+ pp/en/0.html
+
bin_SCRIPTS = \
taler-bank-manage-testing \
taler-exchange-revoke
@@ -21,11 +28,17 @@ EXTRA_DIST = \
$(bin_SCRIPTS) \
$(tosen_DATA) \
update-tos.sh \
+ update-pp.sh \
tos/Makefile \
tos/README \
tos/tos.rst \
tos/conf.py \
tos/locale/de/LC_MESSAGES/tos.po \
+ pp/Makefile \
+ pp/README \
+ pp/tos.rst \
+ pp/conf.py \
+ pp/locale/pp/LC_MESSAGES/pp.po \
auditor-report.tex.j2 \
coverage.sh \
gnunet.tag \
@@ -35,11 +48,15 @@ EXTRA_DIST = \
# Change the set of supported languages here. You should
# also update tos'XX'data and EXTRA_DIST accordingly.
TOS_LANGUAGES="en de"
+PP_LANGUAGES="en de"
# Change the terms-of-service version (Etag) to generate here!
# This value should be incremented whenever there is a substantive
# change in the original text (but not for the translations).
TOS_VERSION=0
+PP_VERSION=0
update-tos:
VERSION=$(TOS_VERSION) ./update-tos.sh $(TOS_LANGUAGES)
+update-pp:
+ VERSION=$(PP_VERSION) ./update-pp.sh $(PP_LANGUAGES)
diff --git a/contrib/pp/.gitignore b/contrib/pp/.gitignore
new file mode 100644
index 00000000..fb83616e
--- /dev/null
+++ b/contrib/pp/.gitignore
@@ -0,0 +1,3 @@
+sphinx.err
+sphinx.log
+_build/
diff --git a/contrib/pp/Makefile.am b/contrib/pp/Makefile.am
deleted file mode 100644
index 21326200..00000000
--- a/contrib/pp/Makefile.am
+++ /dev/null
@@ -1,11 +0,0 @@
-
-# English (en)
-ppendir=$(pkgdatadir)/pp/en
-
-ppen_DATA = \
- en/0.txt \
- en/0.docx \
- en/0.html
-
-EXTRA_DIST = \
- $(ppen_DATA)
diff --git a/contrib/pp/README b/contrib/pp/README
new file mode 100644
index 00000000..e03b8a05
--- /dev/null
+++ b/contrib/pp/README
@@ -0,0 +1,58 @@
+This directory contains the privacy policy (template) for exchange
+operators.
+
+
+Dependencies
+============
+
+Generating a new Privacy Policy requires Sphinx, LaTeX with babel
+packages for all supported languages. On Debian, you should
+at least install:
+
+$ apt install python3-sphinx sphinx-intl texlive-lang-german texlive-lang-english
+
+(NOTE: List may be incomplete.)
+
+
+Updating the Privacy Policy
+===========================
+
+The master file with the Privacy Policy is 'pp.rst'.
+
+If you make substantial changes, you MUST change the "PP_VERSION"
+in contrib/Makefile.am to the new Etag.
+
+To begin the translation into other languages after editing the master
+file, run
+
+$ make gettext
+
+to generate the master PO file. Then, run
+
+$ sphinx-intl update -p _build/locale/ -l de -l fr -l it
+
+to update the PO files for the various languages (extend the list of
+languages as necessary). The PO files for the translators are kept
+at locale/$LANG/LC_MESSAGES/pp.po for the language $LANG.
+
+Once all PO files have been updated with new translations, run
+
+$ make update-pp
+
+in the "contrib/" directory to generate all of the formats. The
+respective make rule calls the '../update-pp.sh' script in the
+contrib/ directory, which calls the 'Makefile' in the pp/
+directory for the various supported languages and file formats
+and then moves the generated files to the target directory
+('contrib/pp/$LANG/$VERSION.$FORMAT')
+
+
+Adding a new language
+=====================
+
+To add a new language $LANG, add $LANG to "PP_LANGUAGES" in
+'contrib/Makefile.am' and run
+
+$ sphinx-intl update -p _build/gettext -l $LANG
+
+to generate the PO template.
diff --git a/contrib/pp/conf.py b/contrib/pp/conf.py
new file mode 100644
index 00000000..9acb9786
--- /dev/null
+++ b/contrib/pp/conf.py
@@ -0,0 +1,282 @@
+"""
+ This file is part of GNU TALER.
+ Copyright (C) 2014-2020 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Lesser General Public License as published by the Free Software
+ Foundation; either version 2.1, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License along with
+ TALER; see the file COPYING. If not, see
+
+ @author Florian Dold
+ @author Benedikt Muller
+ @author Sree Harsha Totakura
+ @author Marcello Stanisci
+"""
+# -*- coding: utf-8 -*-
+#
+# neuro documentation build configuration file, created by
+# sphinx-quickstart on Sat May 31 13:11:06 2014.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys
+import os
+
+sys.path.append(os.path.abspath('_exts'))
+
+#import taler_sphinx_theme
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+needs_sphinx = '1.8.5'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+ 'sphinx.ext.todo',
+ 'sphinx.ext.imgmath',
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+source_suffix = {
+ '.rst': 'restructuredtext',
+}
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'pp'
+
+# General information about the project.
+project = u'pp'
+copyright = u'2014-2020 Taler Systems SA (GPLv3+ or GFDL 1.3+)'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '0'
+# The full version, including alpha/beta/rc tags.
+release = '0'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+# language = "en de"
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build', '_exts', 'cf', 'prebuilt']
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
+# default_role = "ts:type"
+
+locale_dirs = ['locale/']
+gettext_compact = False
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+# If true, keep warnings as "system message" paragraphs in the built documents.
+#keep_warnings = False
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'epub'
+
+#html_theme_path = taler_sphinx_theme.html_theme_path()
+
+#html_sidebars = {'**': ['logo-text.html', 'globaltoc.html', 'searchbox.html']}
+
+rst_epilog = ""
+
+html_show_sphinx = False
+
+html_theme_options = {
+ # Set the name of the project to appear in the sidebar
+ "relbar1": "false",
+ "footer": "false",
+}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# " v documentation".
+html_title = "Taler Privacy Policy"
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+html_short_title = "Privacy Policy"
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+# html_static_path = ['_static']
+
+# Add any extra paths that contain custom files (such as robots.txt or
+# .htaccess) here, relative to this directory. These files are copied
+# directly to the root of the documentation.
+#html_extra_path = []
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+html_show_sphinx = False
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+ # The paper size ('letterpaper' or 'a4paper').
+ #'papersize': 'letterpaper',
+
+ # The font size ('10pt', '11pt' or '12pt').
+ #'pointsize': '10pt',
+
+ # Additional stuff for the LaTeX preamble.
+ #'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+# author, documentclass [howto, manual, or own class]).
+latex_documents = [
+ ('pp', 'pp.tex',
+ 'Privacy Policy', 'GNU Taler team', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+# latex_appendices = ["fdl-1.3"]
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+# -- Options for manual page output ---------------------------------------
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
+
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+#texinfo_no_detailmenu = False
+
+
+# -- Options for epub output ----------------------------
+
+epub_basename = "pp"
+
+epub_title = "Privacy Policy"
diff --git a/contrib/pp/en/0.docx b/contrib/pp/en/0.docx
deleted file mode 100644
index 2318396e..00000000
Binary files a/contrib/pp/en/0.docx and /dev/null differ
diff --git a/contrib/pp/en/0.epub b/contrib/pp/en/0.epub
new file mode 100644
index 00000000..49669a4a
Binary files /dev/null and b/contrib/pp/en/0.epub differ
diff --git a/contrib/pp/en/0.html b/contrib/pp/en/0.html
index febe21e9..1e73557f 100644
--- a/contrib/pp/en/0.html
+++ b/contrib/pp/en/0.html
@@ -1,217 +1,180 @@
-
-
-
-
- Our Privacy Policy
-
-
-
-
-
Privacy Policy
-
- Last Updated: 11.12.2019
-
-
- This
-Privacy Policy describes the policies and procedures of Taler Systems
-SA (“we,” “our,” or “us”) pertaining to the collection,
-use, and disclosure of your information on our sites and related
-mobile applications and products we offer (the “Services” or
-“Taler Wallet”). This Privacy Statement applies to your personal
-data when you use our Services, and does not apply to online websites
- or services that we do not own or control.
-
-
-
OVERVIEW
-
-
Your
-privacy is important to us. We follow a few fundamental principles:
-We don’t ask you for personally identifiable information (defined
-below). That being said, your contact information, such as your phone
-number, social media handle, or email address (depending on how you
-contact us), may be collected when you communicate with us, for
-example to report a bug or other error related to the Taler Wallet.
-We don’t share your information with third parties except when
-strictly required to deliver you our Services and products, or to
-comply with the law. If you have any questions or concerns about this
-policy, please reach out to us at privacy@taler-systems.net.
-
-
-
HOW YOU ACCEPT THIS POLICY
-
-
By
-using our Services or visiting our sites, you agree to the use,
-disclosure, and procedures outlined in this Privacy Policy.
-
-
-
WHAT PERSONAL INFORMATION DO WE COLLECT FROM OUR USERS?
-
-
The
-information we collect from you falls into two categories: (i)
-personally identifiable information (i.e., data that could
-potentially identify you as an individual) (“Personal
-Information”), and (ii) non-personally identifiable information
-(i.e., information that cannot be used to identify who you are)
-(“Non-Personal Information”). This Privacy Policy covers both
-categories and will tell you how we might collect and use each type.
-
-
We
-do our best to not collect any Personal Information from Taler Wallet
-users. We believe that the Taler Wallet never transmits personal
-information to our services without at least clear implied consent,
-and we only process and retain information with a strict business
-need. That being said, when using our Services, we inherently have
- to collect the following information:
-
-
-
-
Bank
- account details necessary when receiving funds from you to top-up
- your wallet or to transfer funds to you when you are being paid via
- Taler. At the current experimental stage, only the pseudonym and
- password you entered in the bank demonstrator is stored.
-
The
- amounts being withdrawn or deposited, with associated unique
- transaction identifiers and cryptographic signatures authorizing the
- transaction. Note that for purchases, we cannot identify the buyer
- from the collected data, so when you spend money, we only receive
- non-personal information.
-
When
- you contact us. We may collect certain information if you choose to
- contact us, for example to report a bug or other error with the
- Taler Wallet. This may include contact information such as your
- name, email address or phone number depending on the method you
- choose to contact us.
+
+
+
+
+ Privacy Policy — Taler Privacy Policy
+
+
+
+
+
+
+
+
+
+
This Privacy Policy describes the policies and procedures of Taler Systems SA
+(“we,” “our,” or “us”) pertaining to the collection, use, and disclosure of
+your information on our sites and related mobile applications and products we
+offer (the “Services” or “Taler Wallet”). This Privacy Statement applies to
+your personal data when you use our Services, and does not apply to online
+websites or services that we do not own or control.
Your privacy is important to us. We follow a few fundamental principles: We
+don’t ask you for personally identifiable information (defined below). That
+being said, your contact information, such as your phone number, social media
+handle, or email address (depending on how you contact us), may be collected
+when you communicate with us, for example to report a bug or other error
+related to the Taler Wallet. We don’t share your information with third
+parties except when strictly required to deliver you our Services and
+products, or to comply with the law. If you have any questions or concerns
+about this policy, please reach out to us at privacy@taler-systems.net.
By using our Services or visiting our sites, you agree to the use, disclosure,
+and procedures outlined in this Privacy Policy.
+
+
+
What personal information do we collect from our users?¶
+
The information we collect from you falls into two categories: (i) personally
+identifiable information (i.e., data that could potentially identify you as an
+individual) (“Personal Information”), and (ii) non-personally identifiable
+information (i.e., information that cannot be used to identify who you are)
+(“Non-Personal Information”). This Privacy Policy covers both categories and
+will tell you how we might collect and use each type.
+
We do our best to not collect any Personal Information from Taler Wallet
+users. We believe that the Taler Wallet never transmits personal information
+to our services without at least clear implied consent, and we only process
+and retain information with a strict business need. That being said, when
+using our Services, we inherently have to collect the following information:
+
+
+
Bank account details necessary when receiving funds from you to top-up your wallet or to transfer funds to you when you are being paid via Taler. At the current experimental stage, only the pseudonym and password you entered in the bank demonstrator is stored.
+
The amounts being withdrawn or deposited, with associated unique transaction identifiers and cryptographic signatures authorizing the transaction. Note that for purchases, we cannot identify the buyer from the collected data, so when you spend money, we only receive non-personal information.
+
When you contact us. We may collect certain information if you choose to contact us, for example to report a bug or other error with the Taler Wallet. This may include contact information such as your name, email address or phone number depending on the method you choose to contact us.
We may process your information for the following reasons:
-
-
-
to
- transfer money as specified by our users (Taler transactions);
-
to
- assist government entities in linking income to the underlying contract
-
to
- support you using the Taler Wallet or to improve our Services
+
+
+
to transfer money as specified by our users (Taler transactions);
+
to assist government entities in linking income to the underlying contract
+
to support you using the Taler Wallet or to improve our Services
-
-
-
HOW WE SHARE AND USE THE INFORMATION WE GATHER
-
-
We
-may share your Personal Data or other information about you only if
-you are a merchant receiving income, with your bank, to the degree
-necessary to execute the payment.
-
We
-retain Personal Data to transfer funds to the accounts designated by
-our users. We may retain Personal Data only for as long as mandated
-by law and required for the wire transfers.
-
We
-primarily use the limited information we receive directly from you to
-enhance the Taler Wallet. Some ways we may use your Personal
-Information are to: Contact you when necessary to respond to your
-comments, answer your questions, or obtain additional information on
-issues related to bugs or errors with the Taler Wallet that you
-reported.
-
-
AGENTS OR THIRD PARTY PARTNERS
-
-
We
-may provide your Personal Information to our employees, contractors,
-agents, service providers, and designees (“Agents”) to enable
-them to perform certain services for us exclusively, including:
-improvement and maintenance of our software and Services. By
-accepting this Privacy Policy, as outlined above, you consent to any
-such transfer.
-
-
-
PROTECTION OF US AND OTHERS
-
-
We
-reserve the right to access, read, preserve, and disclose any
-information that we reasonably believe is necessary to comply with
-the law or a court order.
-
-
-
WHAT PERSONAL INFORMATION CAN I ACCESS OR CHANGE?
-
-
You
-can request access to the information we have collected from you. You
-can do this by contacting us at privacy@taler-systems.net. We will
-make sure to provide you with a copy of the data we process about
-you. To comply with your request, we may ask you to verify your
-identity. We will fulfill your request by sending your copy
-electronically. For any subsequent access request, we may charge you
-with an administrative fee. If you believe that the information we
-have collected is incorrect, you are welcome to contact us so we can
-update it and keep your data accurate. Any data that is no longer
-needed for purposes specified in the “How We Use the Information We
-Gather” section will be deleted after ninety (90) days.
-
-
-
DATA RETENTION
-
-
If
-you uninstall the Taler Wallet mobile applications from your device,
-or request that your information be deleted, we still may retain some
-information that you have provided to us to maintain the Taler Wallet
-or to comply with relevant laws.
-
-
-
DATA SECURITY
-
-
We are committed to making sure your information
-is protected. We employ several physical and electronic safeguards to
-keep your information safe, including encrypted user passwords, two
-factor verification and authentication on passwords where possible,
-and securing connections with industry standard transport layer
-security. You are also welcome to contact us using GnuPG encrypted
-e-mail. Even with all these precautions, we cannot fully guarantee
-against the access, disclosure, alteration, or deletion of data
-through events, including but not limited to hardware or software
-failure or unauthorized use. Any information that you provide to us
-is done so entirely at your own risk.
-
-
CHANGES AND UPDATES TO PRIVACY POLICY
-
-
We
-reserve the right to update and revise this privacy policy at any
-time. We occasionally review this Privacy Policy to make sure it
-complies with applicable laws and conforms to changes in our
-business. We may need to update this Privacy Policy, and we reserve
-the right to do so at any time. If we do revise this Privacy Policy,
-we will update the “Effective Date” at the bottom of this page so
-that you can tell if it has changed since your last visit. As we
-generally do not collect contact information and also do not track
-your visits, we will not be able to notify you directly. However, the
-Taler Wallet may inform you about a change in the privacy policy once
-it detects that the policy has changed. Please review this Privacy
-Policy regularly to ensure that you are aware of its terms. Any use
-of our Services after an amendment to our Privacy Policy constitutes
-your acceptance to the revised or amended agreement.
-
-
-
INTERNATIONAL USERS AND VISITORS
-
-
Our
-Services are hosted in Switzerland. If you are a user accessing the
-Services from the European Union, Asia, US, or any other region with
-laws or regulations governing personal data collection, use, and
-disclosure that differ from Swiss laws, please be advised that
-through your continued use of the Services, which is governed by
-Swiss law, you are transferring your Personal Information to
-Switzerland and you consent to that transfer.
-
-
-
QUESTIONS
-
Please
-contact us at privacy@taler-systems.net if you have questions about
-our privacy practices that are not addressed in this Privacy
- Statement.
-
We may share your Personal Data or other information about you only if you are
+a merchant receiving income, with your bank, to the degree necessary to
+execute the payment.
+
We retain Personal Data to transfer funds to the accounts designated by our
+users. We may retain Personal Data only for as long as mandated by law and
+required for the wire transfers.
+
We primarily use the limited information we receive directly from you to
+enhance the Taler Wallet. Some ways we may use your Personal Information are
+to: Contact you when necessary to respond to your comments, answer your
+questions, or obtain additional information on issues related to bugs or
+errors with the Taler Wallet that you reported.
We may provide your Personal Information to our employees, contractors,
+agents, service providers, and designees (“Agents”) to enable them to perform
+certain services for us exclusively, including: improvement and maintenance of
+our software and Services. By accepting this Privacy Policy, as outlined
+above, you consent to any such transfer.
We reserve the right to access, read, preserve, and disclose any information
+that we reasonably believe is necessary to comply with the law or a court
+order.
+
+
+
What personal information can I access or change?¶
+
You can request access to the information we have collected from you. You can
+do this by contacting us at privacy@taler-systems.net. We will make sure to
+provide you with a copy of the data we process about you. To comply with your
+request, we may ask you to verify your identity. We will fulfill your request
+by sending your copy electronically. For any subsequent access request, we may
+charge you with an administrative fee. If you believe that the information we
+have collected is incorrect, you are welcome to contact us so we can update it
+and keep your data accurate. Any data that is no longer needed for purposes
+specified in the “How We Use the Information We Gather” section will be
+deleted after ninety (90) days.
If you uninstall the Taler Wallet mobile applications from your device, or
+request that your information be deleted, we still may retain some information
+that you have provided to us to maintain the Taler Wallet or to comply with
+relevant laws.
We are committed to making sure your information is protected. We employ
+several physical and electronic safeguards to keep your information safe,
+including encrypted user passwords, two factor verification and authentication
+on passwords where possible, and securing connections with industry standard
+transport layer security. You are also welcome to contact us using GnuPG
+encrypted e-mail. Even with all these precautions, we cannot fully guarantee
+against the access, disclosure, alteration, or deletion of data through
+events, including but not limited to hardware or software failure or
+unauthorized use. Any information that you provide to us is done so entirely
+at your own risk.
We reserve the right to update and revise this privacy policy at any time. We
+occasionally review this Privacy Policy to make sure it complies with
+applicable laws and conforms to changes in our business. We may need to update
+this Privacy Policy, and we reserve the right to do so at any time. If we do
+revise this Privacy Policy, we will update the “Effective Date” at the bottom
+of this page so that you can tell if it has changed since your last visit. As
+we generally do not collect contact information and also do not track your
+visits, we will not be able to notify you directly. However, the Taler Wallet
+may inform you about a change in the privacy policy once it detects that the
+policy has changed. Please review this Privacy Policy regularly to ensure that
+you are aware of its terms. Any use of our Services after an amendment to our
+Privacy Policy constitutes your acceptance to the revised or amended
+agreement.
Our Services are hosted in Switzerland. If you are a user accessing the
+Services from the European Union, Asia, US, or any other region with laws or
+regulations governing personal data collection, use, and disclosure that
+differ from Swiss laws, please be advised that through your continued use of
+the Services, which is governed by Swiss law, you are transferring your
+Personal Information to Switzerland and you consent to that transfer.
Please contact us at privacy@taler-systems.net if you have questions about our
+privacy practices that are not addressed in this Privacy Statement.
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/contrib/pp/en/0.pdf b/contrib/pp/en/0.pdf
new file mode 100644
index 00000000..f594aa3b
Binary files /dev/null and b/contrib/pp/en/0.pdf differ
diff --git a/contrib/pp/en/0.txt b/contrib/pp/en/0.txt
index 98301b2f..a5194d32 100644
--- a/contrib/pp/en/0.txt
+++ b/contrib/pp/en/0.txt
@@ -1,102 +1,202 @@
-'''Privacy Policy'''
-
+Privacy Policy
+**************
Last Updated: 11.12.2019
-This Privacy Policy describes the policies and procedures of Taler Systems SA (“we,” “our,” or “us”) pertaining to the collection, use, and disclosure of your information on our sites and related mobile applications and products we offer (the “Services” or “Taler Wallet”). This Privacy Statement applies to your personal data when you use our Services, and does not apply to online websites or services that we do not own or control.
+This Privacy Policy describes the policies and procedures of Taler
+Systems SA (“we,” “our,” or “us”) pertaining to the collection, use,
+and disclosure of your information on our sites and related mobile
+applications and products we offer (the “Services” or “Taler Wallet”).
+This Privacy Statement applies to your personal data when you use our
+Services, and does not apply to online websites or services that we do
+not own or control.
-OVERVIEW
+Overview
========
-Your privacy is important to us. We follow a few fundamental principles: We don’t ask you for personally identifiable information (defined below). That being said, your contact information, such as your phone number, social media handle, or email address (depending on how you contact us), may be collected when you communicate with us, for example to report a bug or other error related to the Taler Wallet. We don’t share your information with third parties except when strictly required to deliver you our Services and products, or to comply with the law. If you have any questions or concerns about this policy, please reach out to us at privacy@taler-systems.net.
+Your privacy is important to us. We follow a few fundamental
+principles: We don’t ask you for personally identifiable information
+(defined below). That being said, your contact information, such as
+your phone number, social media handle, or email address (depending on
+how you contact us), may be collected when you communicate with us,
+for example to report a bug or other error related to the Taler
+Wallet. We don’t share your information with third parties except when
+strictly required to deliver you our Services and products, or to
+comply with the law. If you have any questions or concerns about this
+policy, please reach out to us at privacy@taler-systems.net.
-HOW YOU ACCEPT THIS POLICY
+How you accept this policy
==========================
-By using our Services or visiting our sites, you agree to the use, disclosure, and procedures outlined in this Privacy Policy.
+By using our Services or visiting our sites, you agree to the use,
+disclosure, and procedures outlined in this Privacy Policy.
-WHAT PERSONAL INFORMATION DO WE COLLECT FROM OUR USERS?
+What personal information do we collect from our users?
=======================================================
-The information we collect from you falls into two categories: (i) personally identifiable information (i.e., data that could potentially identify you as an individual) (“Personal Information”), and (ii) non-personally identifiable information (i.e., information that cannot be used to identify who you are) (“Non-Personal Information”). This Privacy Policy covers both categories and will tell you how we might collect and use each type.
-
-We do our best to not collect any Personal Information from Taler Wallet users. We believe that the Taler Wallet never transmits personal information to our services without at least clear implied consent, and we only process and retain information with a strict business need. That being said, when using our Services, we inherently have to collect the following information:
-
-* Bank account details necessary when receiving funds from you to top-up your wallet or to transfer funds to you when you are being paid via Taler. At the current experimental stage, only the pseudonym and password you entered in the bank demonstrator is stored.
-
-* The amounts being withdrawn or deposited, with associated unique transaction identifiers and cryptographic signatures authorizing the transaction. Note that for purchases, we cannot identify the buyer from the collected data, so when you spend money, we only receive non-personal information.
-
-* When you contact us. We may collect certain information if you choose to contact us, for example to report a bug or other error with the Taler Wallet. This may include contact information such as your name, email address or phone number depending on the method you choose to contact us.
-
-
-HOW WE COLLECT AND PROCESS INFORMATION
+The information we collect from you falls into two categories: (i)
+personally identifiable information (i.e., data that could potentially
+identify you as an individual) (“Personal Information”), and (ii) non-
+personally identifiable information (i.e., information that cannot be
+used to identify who you are) (“Non-Personal Information”). This
+Privacy Policy covers both categories and will tell you how we might
+collect and use each type.
+
+We do our best to not collect any Personal Information from Taler
+Wallet users. We believe that the Taler Wallet never transmits
+personal information to our services without at least clear implied
+consent, and we only process and retain information with a strict
+business need. That being said, when using our Services, we inherently
+have to collect the following information:
+
+ * Bank account details necessary when receiving funds from you to
+ top-up your wallet or to transfer funds to you when you are being
+ paid via Taler. At the current experimental stage, only the
+ pseudonym and password you entered in the bank demonstrator is
+ stored.
+
+ * The amounts being withdrawn or deposited, with associated unique
+ transaction identifiers and cryptographic signatures authorizing
+ the transaction. Note that for purchases, we cannot identify the
+ buyer from the collected data, so when you spend money, we only
+ receive non-personal information.
+
+ * When you contact us. We may collect certain information if you
+ choose to contact us, for example to report a bug or other error
+ with the Taler Wallet. This may include contact information such
+ as your name, email address or phone number depending on the
+ method you choose to contact us.
+
+
+How we collect and process information
======================================
We may process your information for the following reasons:
-* to transfer money as specified by our users (Taler transactions);
+ * to transfer money as specified by our users (Taler transactions);
-* to assist government entities in linking income to the underlying contract
+ * to assist government entities in linking income to the underlying
+ contract
-* to support you using the Taler Wallet or to improve our Services
+ * to support you using the Taler Wallet or to improve our Services
-HOW WE SHARE AND USE THE INFORMATION WE GATHER
+How we share and use the information we gather
==============================================
-We may share your Personal Data or other information about you only if you are a merchant receiving income, with your bank, to the degree necessary to execute the payment.
+We may share your Personal Data or other information about you only if
+you are a merchant receiving income, with your bank, to the degree
+necessary to execute the payment.
-We retain Personal Data to transfer funds to the accounts designated by our users. We may retain Personal Data only for as long as mandated by law and required for the wire transfers.
+We retain Personal Data to transfer funds to the accounts designated
+by our users. We may retain Personal Data only for as long as mandated
+by law and required for the wire transfers.
-We primarily use the limited information we receive directly from you to enhance the Taler Wallet. Some ways we may use your Personal Information are to: Contact you when necessary to respond to your comments, answer your questions, or obtain additional information on issues related to bugs or errors with the Taler Wallet that you reported.
+We primarily use the limited information we receive directly from you
+to enhance the Taler Wallet. Some ways we may use your Personal
+Information are to: Contact you when necessary to respond to your
+comments, answer your questions, or obtain additional information on
+issues related to bugs or errors with the Taler Wallet that you
+reported.
-AGENTS OR THIRD PARTY PARTNERS
+Agents or third party partners
==============================
-We may provide your Personal Information to our employees, contractors, agents, service providers, and designees (“Agents”) to enable them to perform certain services for us exclusively, including: improvement and maintenance of our software and Services. By accepting this Privacy Policy, as outlined above, you consent to any such transfer.
+We may provide your Personal Information to our employees,
+contractors, agents, service providers, and designees (“Agents”) to
+enable them to perform certain services for us exclusively, including:
+improvement and maintenance of our software and Services. By accepting
+this Privacy Policy, as outlined above, you consent to any such
+transfer.
-PROTECTION OF US AND OTHERS
+Protection of us and others
===========================
-We reserve the right to access, read, preserve, and disclose any information that we reasonably believe is necessary to comply with the law or a court order.
+We reserve the right to access, read, preserve, and disclose any
+information that we reasonably believe is necessary to comply with the
+law or a court order.
-WHAT PERSONAL INFORMATION CAN I ACCESS OR CHANGE?
+What personal information can I access or change?
=================================================
-You can request access to the information we have collected from you. You can do this by contacting us at privacy@taler-systems.net. We will make sure to provide you with a copy of the data we process about you. To comply with your request, we may ask you to verify your identity. We will fulfill your request by sending your copy electronically. For any subsequent access request, we may charge you with an administrative fee. If you believe that the information we have collected is incorrect, you are welcome to contact us so we can update it and keep your data accurate. Any data that is no longer needed for purposes specified in the “How We Use the Information We Gather” section will be deleted after ninety (90) days.
+You can request access to the information we have collected from you.
+You can do this by contacting us at privacy@taler-systems.net. We will
+make sure to provide you with a copy of the data we process about you.
+To comply with your request, we may ask you to verify your identity.
+We will fulfill your request by sending your copy electronically. For
+any subsequent access request, we may charge you with an
+administrative fee. If you believe that the information we have
+collected is incorrect, you are welcome to contact us so we can update
+it and keep your data accurate. Any data that is no longer needed for
+purposes specified in the “How We Use the Information We Gather”
+section will be deleted after ninety (90) days.
-DATA RETENTION
+Data retention
==============
-If you uninstall the Taler Wallet mobile applications from your device, or request that your information be deleted, we still may retain some information that you have provided to us to maintain the Taler Wallet or to comply with relevant laws.
+If you uninstall the Taler Wallet mobile applications from your
+device, or request that your information be deleted, we still may
+retain some information that you have provided to us to maintain the
+Taler Wallet or to comply with relevant laws.
-DATA SECURITY
+Data security
=============
-We are committed to making sure your information is protected. We employ several physical and electronic safeguards to keep your information safe, including encrypted user passwords, two factor verification and authentication on passwords where possible, and securing connections with industry standard transport layer security. You are also welcome to contact us using GnuPG encrypted e-mail. Even with all these precautions, we cannot fully guarantee against the access, disclosure, alteration, or deletion of data through events, including but not limited to hardware or software failure or unauthorized use. Any information that you provide to us is done so entirely at your own risk.
+We are committed to making sure your information is protected. We
+employ several physical and electronic safeguards to keep your
+information safe, including encrypted user passwords, two factor
+verification and authentication on passwords where possible, and
+securing connections with industry standard transport layer security.
+You are also welcome to contact us using GnuPG encrypted e-mail. Even
+with all these precautions, we cannot fully guarantee against the
+access, disclosure, alteration, or deletion of data through events,
+including but not limited to hardware or software failure or
+unauthorized use. Any information that you provide to us is done so
+entirely at your own risk.
-CHANGES AND UPDATES TO PRIVACY POLICY
+Changes and updates to privacy policy
=====================================
-We reserve the right to update and revise this privacy policy at any time. We occasionally review this Privacy Policy to make sure it complies with applicable laws and conforms to changes in our business. We may need to update this Privacy Policy, and we reserve the right to do so at any time. If we do revise this Privacy Policy, we will update the “Effective Date” at the bottom of this page so that you can tell if it has changed since your last visit. As we generally do not collect contact information and also do not track your visits, we will not be able to notify you directly. However, the Taler Wallet may inform you about a change in the privacy policy once it detects that the policy has changed. Please review this Privacy Policy regularly to ensure that you are aware of its terms. Any use of our Services after an amendment to our Privacy Policy constitutes your acceptance to the revised or amended agreement.
-
-
-INTERNATIONAL USERS AND VISITORS
+We reserve the right to update and revise this privacy policy at any
+time. We occasionally review this Privacy Policy to make sure it
+complies with applicable laws and conforms to changes in our business.
+We may need to update this Privacy Policy, and we reserve the right to
+do so at any time. If we do revise this Privacy Policy, we will update
+the “Effective Date” at the bottom of this page so that you can tell
+if it has changed since your last visit. As we generally do not
+collect contact information and also do not track your visits, we will
+not be able to notify you directly. However, the Taler Wallet may
+inform you about a change in the privacy policy once it detects that
+the policy has changed. Please review this Privacy Policy regularly to
+ensure that you are aware of its terms. Any use of our Services after
+an amendment to our Privacy Policy constitutes your acceptance to the
+revised or amended agreement.
+
+
+International users and visitors
================================
-Our Services are hosted in Switzerland. If you are a user accessing the Services from the European Union, Asia, US, or any other region with laws or regulations governing personal data collection, use, and disclosure that differ from Swiss laws, please be advised that through your continued use of the Services, which is governed by Swiss law, you are transferring your Personal Information to Switzerland and you consent to that transfer.
+Our Services are hosted in Switzerland. If you are a user accessing
+the Services from the European Union, Asia, US, or any other region
+with laws or regulations governing personal data collection, use, and
+disclosure that differ from Swiss laws, please be advised that through
+your continued use of the Services, which is governed by Swiss law,
+you are transferring your Personal Information to Switzerland and you
+consent to that transfer.
-QUESTIONS
+Questions
=========
-Please contact us at privacy@taler-systems.net if you have questions about our privacy practices that are not addressed in this Privacy Statement.
+Please contact us at privacy@taler-systems.net if you have questions
+about our privacy practices that are not addressed in this Privacy
+Statement.
diff --git a/contrib/pp/en/0.xml b/contrib/pp/en/0.xml
new file mode 100644
index 00000000..3050c92b
--- /dev/null
+++ b/contrib/pp/en/0.xml
@@ -0,0 +1,167 @@
+
+
+
+
+
+ Privacy Policy
+ Last Updated: 11.12.2019
+ This Privacy Policy describes the policies and procedures of Taler Systems SA
+ (“we,” “our,” or “us”) pertaining to the collection, use, and disclosure of
+ your information on our sites and related mobile applications and products we
+ offer (the “Services” or “Taler Wallet”). This Privacy Statement applies to
+ your personal data when you use our Services, and does not apply to online
+ websites or services that we do not own or control.
+
+ Overview
+ Your privacy is important to us. We follow a few fundamental principles: We
+ don’t ask you for personally identifiable information (defined below). That
+ being said, your contact information, such as your phone number, social media
+ handle, or email address (depending on how you contact us), may be collected
+ when you communicate with us, for example to report a bug or other error
+ related to the Taler Wallet. We don’t share your information with third
+ parties except when strictly required to deliver you our Services and
+ products, or to comply with the law. If you have any questions or concerns
+ about this policy, please reach out to us at privacy@taler-systems.net.
+
+
+ How you accept this policy
+ By using our Services or visiting our sites, you agree to the use, disclosure,
+ and procedures outlined in this Privacy Policy.
+
+
+ What personal information do we collect from our users?
+ The information we collect from you falls into two categories: (i) personally
+ identifiable information (i.e., data that could potentially identify you as an
+ individual) (“Personal Information”), and (ii) non-personally identifiable
+ information (i.e., information that cannot be used to identify who you are)
+ (“Non-Personal Information”). This Privacy Policy covers both categories and
+ will tell you how we might collect and use each type.
+ We do our best to not collect any Personal Information from Taler Wallet
+ users. We believe that the Taler Wallet never transmits personal information
+ to our services without at least clear implied consent, and we only process
+ and retain information with a strict business need. That being said, when
+ using our Services, we inherently have to collect the following information:
+
+
+
+ Bank account details necessary when receiving funds from you to top-up your wallet or to transfer funds to you when you are being paid via Taler. At the current experimental stage, only the pseudonym and password you entered in the bank demonstrator is stored.
+
+
+ The amounts being withdrawn or deposited, with associated unique transaction identifiers and cryptographic signatures authorizing the transaction. Note that for purchases, we cannot identify the buyer from the collected data, so when you spend money, we only receive non-personal information.
+
+
+ When you contact us. We may collect certain information if you choose to contact us, for example to report a bug or other error with the Taler Wallet. This may include contact information such as your name, email address or phone number depending on the method you choose to contact us.
+
+
+
+
+
+ How we collect and process information
+ We may process your information for the following reasons:
+
+
+
+ to transfer money as specified by our users (Taler transactions);
+
+
+ to assist government entities in linking income to the underlying contract
+
+
+ to support you using the Taler Wallet or to improve our Services
+
+
+
+
+
+ How we share and use the information we gather
+ We may share your Personal Data or other information about you only if you are
+ a merchant receiving income, with your bank, to the degree necessary to
+ execute the payment.
+ We retain Personal Data to transfer funds to the accounts designated by our
+ users. We may retain Personal Data only for as long as mandated by law and
+ required for the wire transfers.
+ We primarily use the limited information we receive directly from you to
+ enhance the Taler Wallet. Some ways we may use your Personal Information are
+ to: Contact you when necessary to respond to your comments, answer your
+ questions, or obtain additional information on issues related to bugs or
+ errors with the Taler Wallet that you reported.
+
+
+ Agents or third party partners
+ We may provide your Personal Information to our employees, contractors,
+ agents, service providers, and designees (“Agents”) to enable them to perform
+ certain services for us exclusively, including: improvement and maintenance of
+ our software and Services. By accepting this Privacy Policy, as outlined
+ above, you consent to any such transfer.
+
+
+ Protection of us and others
+ We reserve the right to access, read, preserve, and disclose any information
+ that we reasonably believe is necessary to comply with the law or a court
+ order.
+
+
+ What personal information can I access or change?
+ You can request access to the information we have collected from you. You can
+ do this by contacting us at privacy@taler-systems.net. We will make sure to
+ provide you with a copy of the data we process about you. To comply with your
+ request, we may ask you to verify your identity. We will fulfill your request
+ by sending your copy electronically. For any subsequent access request, we may
+ charge you with an administrative fee. If you believe that the information we
+ have collected is incorrect, you are welcome to contact us so we can update it
+ and keep your data accurate. Any data that is no longer needed for purposes
+ specified in the “How We Use the Information We Gather” section will be
+ deleted after ninety (90) days.
+
+
+ Data retention
+ If you uninstall the Taler Wallet mobile applications from your device, or
+ request that your information be deleted, we still may retain some information
+ that you have provided to us to maintain the Taler Wallet or to comply with
+ relevant laws.
+
+
+ Data security
+ We are committed to making sure your information is protected. We employ
+ several physical and electronic safeguards to keep your information safe,
+ including encrypted user passwords, two factor verification and authentication
+ on passwords where possible, and securing connections with industry standard
+ transport layer security. You are also welcome to contact us using GnuPG
+ encrypted e-mail. Even with all these precautions, we cannot fully guarantee
+ against the access, disclosure, alteration, or deletion of data through
+ events, including but not limited to hardware or software failure or
+ unauthorized use. Any information that you provide to us is done so entirely
+ at your own risk.
+
+
+ Changes and updates to privacy policy
+ We reserve the right to update and revise this privacy policy at any time. We
+ occasionally review this Privacy Policy to make sure it complies with
+ applicable laws and conforms to changes in our business. We may need to update
+ this Privacy Policy, and we reserve the right to do so at any time. If we do
+ revise this Privacy Policy, we will update the “Effective Date” at the bottom
+ of this page so that you can tell if it has changed since your last visit. As
+ we generally do not collect contact information and also do not track your
+ visits, we will not be able to notify you directly. However, the Taler Wallet
+ may inform you about a change in the privacy policy once it detects that the
+ policy has changed. Please review this Privacy Policy regularly to ensure that
+ you are aware of its terms. Any use of our Services after an amendment to our
+ Privacy Policy constitutes your acceptance to the revised or amended
+ agreement.
+
+
+ International users and visitors
+ Our Services are hosted in Switzerland. If you are a user accessing the
+ Services from the European Union, Asia, US, or any other region with laws or
+ regulations governing personal data collection, use, and disclosure that
+ differ from Swiss laws, please be advised that through your continued use of
+ the Services, which is governed by Swiss law, you are transferring your
+ Personal Information to Switzerland and you consent to that transfer.
+
+
+ Questions
+ Please contact us at privacy@taler-systems.net if you have questions about our
+ privacy practices that are not addressed in this Privacy Statement.
+
+
+
diff --git a/contrib/pp/locale/de/LC_MESSAGES/pp.po b/contrib/pp/locale/de/LC_MESSAGES/pp.po
new file mode 100644
index 00000000..b9544472
--- /dev/null
+++ b/contrib/pp/locale/de/LC_MESSAGES/pp.po
@@ -0,0 +1,283 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) 2014-2020 Taler Systems SA (GPLv3+ or GFDL 1.3+)
+# This file is distributed under the same license as the pp package.
+# FIRST AUTHOR , 2020.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: pp 0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2020-02-07 00:51+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: LANGUAGE \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.6.0\n"
+
+#: ../../pp.rst:2
+msgid "Privacy Policy"
+msgstr ""
+
+#: ../../pp.rst:4
+msgid "Last Updated: 11.12.2019"
+msgstr ""
+
+#: ../../pp.rst:6
+msgid ""
+"This Privacy Policy describes the policies and procedures of Taler "
+"Systems SA (“we,” “our,” or “us”) pertaining to the collection, use, and "
+"disclosure of your information on our sites and related mobile "
+"applications and products we offer (the “Services” or “Taler Wallet”). "
+"This Privacy Statement applies to your personal data when you use our "
+"Services, and does not apply to online websites or services that we do "
+"not own or control."
+msgstr ""
+
+#: ../../pp.rst:15
+msgid "Overview"
+msgstr ""
+
+#: ../../pp.rst:17
+msgid ""
+"Your privacy is important to us. We follow a few fundamental principles: "
+"We don’t ask you for personally identifiable information (defined below)."
+" That being said, your contact information, such as your phone number, "
+"social media handle, or email address (depending on how you contact us), "
+"may be collected when you communicate with us, for example to report a "
+"bug or other error related to the Taler Wallet. We don’t share your "
+"information with third parties except when strictly required to deliver "
+"you our Services and products, or to comply with the law. If you have any"
+" questions or concerns about this policy, please reach out to us at "
+"privacy@taler-systems.net."
+msgstr ""
+
+#: ../../pp.rst:29
+msgid "How you accept this policy"
+msgstr ""
+
+#: ../../pp.rst:31
+msgid ""
+"By using our Services or visiting our sites, you agree to the use, "
+"disclosure, and procedures outlined in this Privacy Policy."
+msgstr ""
+
+#: ../../pp.rst:36
+msgid "What personal information do we collect from our users?"
+msgstr ""
+
+#: ../../pp.rst:38
+msgid ""
+"The information we collect from you falls into two categories: (i) "
+"personally identifiable information (i.e., data that could potentially "
+"identify you as an individual) (“Personal Information”), and (ii) non-"
+"personally identifiable information (i.e., information that cannot be "
+"used to identify who you are) (“Non-Personal Information”). This Privacy "
+"Policy covers both categories and will tell you how we might collect and "
+"use each type."
+msgstr ""
+
+#: ../../pp.rst:45
+msgid ""
+"We do our best to not collect any Personal Information from Taler Wallet "
+"users. We believe that the Taler Wallet never transmits personal "
+"information to our services without at least clear implied consent, and "
+"we only process and retain information with a strict business need. That "
+"being said, when using our Services, we inherently have to collect the "
+"following information:"
+msgstr ""
+
+#: ../../pp.rst:51
+msgid ""
+"Bank account details necessary when receiving funds from you to top-up "
+"your wallet or to transfer funds to you when you are being paid via "
+"Taler. At the current experimental stage, only the pseudonym and password"
+" you entered in the bank demonstrator is stored."
+msgstr ""
+
+#: ../../pp.rst:53
+msgid ""
+"The amounts being withdrawn or deposited, with associated unique "
+"transaction identifiers and cryptographic signatures authorizing the "
+"transaction. Note that for purchases, we cannot identify the buyer from "
+"the collected data, so when you spend money, we only receive non-personal"
+" information."
+msgstr ""
+
+#: ../../pp.rst:55
+msgid ""
+"When you contact us. We may collect certain information if you choose to "
+"contact us, for example to report a bug or other error with the Taler "
+"Wallet. This may include contact information such as your name, email "
+"address or phone number depending on the method you choose to contact us."
+msgstr ""
+
+#: ../../pp.rst:59
+msgid "How we collect and process information"
+msgstr ""
+
+#: ../../pp.rst:61
+msgid "We may process your information for the following reasons:"
+msgstr ""
+
+#: ../../pp.rst:63
+msgid "to transfer money as specified by our users (Taler transactions);"
+msgstr ""
+
+#: ../../pp.rst:64
+msgid "to assist government entities in linking income to the underlying contract"
+msgstr ""
+
+#: ../../pp.rst:65
+msgid "to support you using the Taler Wallet or to improve our Services"
+msgstr ""
+
+#: ../../pp.rst:69
+msgid "How we share and use the information we gather"
+msgstr ""
+
+#: ../../pp.rst:71
+msgid ""
+"We may share your Personal Data or other information about you only if "
+"you are a merchant receiving income, with your bank, to the degree "
+"necessary to execute the payment."
+msgstr ""
+
+#: ../../pp.rst:75
+msgid ""
+"We retain Personal Data to transfer funds to the accounts designated by "
+"our users. We may retain Personal Data only for as long as mandated by "
+"law and required for the wire transfers."
+msgstr ""
+
+#: ../../pp.rst:79
+msgid ""
+"We primarily use the limited information we receive directly from you to "
+"enhance the Taler Wallet. Some ways we may use your Personal Information "
+"are to: Contact you when necessary to respond to your comments, answer "
+"your questions, or obtain additional information on issues related to "
+"bugs or errors with the Taler Wallet that you reported."
+msgstr ""
+
+#: ../../pp.rst:87
+msgid "Agents or third party partners"
+msgstr ""
+
+#: ../../pp.rst:89
+msgid ""
+"We may provide your Personal Information to our employees, contractors, "
+"agents, service providers, and designees (“Agents”) to enable them to "
+"perform certain services for us exclusively, including: improvement and "
+"maintenance of our software and Services. By accepting this Privacy "
+"Policy, as outlined above, you consent to any such transfer."
+msgstr ""
+
+#: ../../pp.rst:97
+msgid "Protection of us and others"
+msgstr ""
+
+#: ../../pp.rst:99
+msgid ""
+"We reserve the right to access, read, preserve, and disclose any "
+"information that we reasonably believe is necessary to comply with the "
+"law or a court order."
+msgstr ""
+
+#: ../../pp.rst:105
+msgid "What personal information can I access or change?"
+msgstr ""
+
+#: ../../pp.rst:107
+msgid ""
+"You can request access to the information we have collected from you. You"
+" can do this by contacting us at privacy@taler-systems.net. We will make "
+"sure to provide you with a copy of the data we process about you. To "
+"comply with your request, we may ask you to verify your identity. We will"
+" fulfill your request by sending your copy electronically. For any "
+"subsequent access request, we may charge you with an administrative fee. "
+"If you believe that the information we have collected is incorrect, you "
+"are welcome to contact us so we can update it and keep your data "
+"accurate. Any data that is no longer needed for purposes specified in the"
+" “How We Use the Information We Gather” section will be deleted after "
+"ninety (90) days."
+msgstr ""
+
+#: ../../pp.rst:120
+msgid "Data retention"
+msgstr ""
+
+#: ../../pp.rst:122
+msgid ""
+"If you uninstall the Taler Wallet mobile applications from your device, "
+"or request that your information be deleted, we still may retain some "
+"information that you have provided to us to maintain the Taler Wallet or "
+"to comply with relevant laws."
+msgstr ""
+
+#: ../../pp.rst:129
+msgid "Data security"
+msgstr ""
+
+#: ../../pp.rst:131
+msgid ""
+"We are committed to making sure your information is protected. We employ "
+"several physical and electronic safeguards to keep your information safe,"
+" including encrypted user passwords, two factor verification and "
+"authentication on passwords where possible, and securing connections with"
+" industry standard transport layer security. You are also welcome to "
+"contact us using GnuPG encrypted e-mail. Even with all these precautions,"
+" we cannot fully guarantee against the access, disclosure, alteration, or"
+" deletion of data through events, including but not limited to hardware "
+"or software failure or unauthorized use. Any information that you provide"
+" to us is done so entirely at your own risk."
+msgstr ""
+
+#: ../../pp.rst:144
+msgid "Changes and updates to privacy policy"
+msgstr ""
+
+#: ../../pp.rst:146
+msgid ""
+"We reserve the right to update and revise this privacy policy at any "
+"time. We occasionally review this Privacy Policy to make sure it complies"
+" with applicable laws and conforms to changes in our business. We may "
+"need to update this Privacy Policy, and we reserve the right to do so at "
+"any time. If we do revise this Privacy Policy, we will update the "
+"“Effective Date” at the bottom of this page so that you can tell if it "
+"has changed since your last visit. As we generally do not collect contact"
+" information and also do not track your visits, we will not be able to "
+"notify you directly. However, the Taler Wallet may inform you about a "
+"change in the privacy policy once it detects that the policy has changed."
+" Please review this Privacy Policy regularly to ensure that you are aware"
+" of its terms. Any use of our Services after an amendment to our Privacy "
+"Policy constitutes your acceptance to the revised or amended agreement."
+msgstr ""
+
+#: ../../pp.rst:162
+msgid "International users and visitors"
+msgstr ""
+
+#: ../../pp.rst:164
+msgid ""
+"Our Services are hosted in Switzerland. If you are a user accessing the "
+"Services from the European Union, Asia, US, or any other region with laws"
+" or regulations governing personal data collection, use, and disclosure "
+"that differ from Swiss laws, please be advised that through your "
+"continued use of the Services, which is governed by Swiss law, you are "
+"transferring your Personal Information to Switzerland and you consent to "
+"that transfer."
+msgstr ""
+
+#: ../../pp.rst:173
+msgid "Questions"
+msgstr ""
+
+#: ../../pp.rst:175
+msgid ""
+"Please contact us at privacy@taler-systems.net if you have questions "
+"about our privacy practices that are not addressed in this Privacy "
+"Statement."
+msgstr ""
+
diff --git a/contrib/pp/pp.rst b/contrib/pp/pp.rst
new file mode 100644
index 00000000..d37c10c2
--- /dev/null
+++ b/contrib/pp/pp.rst
@@ -0,0 +1,176 @@
+Privacy Policy
+==============
+
+Last Updated: 11.12.2019
+
+This Privacy Policy describes the policies and procedures of Taler Systems SA
+(“we,” “our,” or “us”) pertaining to the collection, use, and disclosure of
+your information on our sites and related mobile applications and products we
+offer (the “Services” or “Taler Wallet”). This Privacy Statement applies to
+your personal data when you use our Services, and does not apply to online
+websites or services that we do not own or control.
+
+
+Overview
+--------
+
+Your privacy is important to us. We follow a few fundamental principles: We
+don’t ask you for personally identifiable information (defined below). That
+being said, your contact information, such as your phone number, social media
+handle, or email address (depending on how you contact us), may be collected
+when you communicate with us, for example to report a bug or other error
+related to the Taler Wallet. We don’t share your information with third
+parties except when strictly required to deliver you our Services and
+products, or to comply with the law. If you have any questions or concerns
+about this policy, please reach out to us at privacy@taler-systems.net.
+
+
+How you accept this policy
+--------------------------
+
+By using our Services or visiting our sites, you agree to the use, disclosure,
+and procedures outlined in this Privacy Policy.
+
+
+What personal information do we collect from our users?
+-------------------------------------------------------
+
+The information we collect from you falls into two categories: (i) personally
+identifiable information (i.e., data that could potentially identify you as an
+individual) (“Personal Information”), and (ii) non-personally identifiable
+information (i.e., information that cannot be used to identify who you are)
+(“Non-Personal Information”). This Privacy Policy covers both categories and
+will tell you how we might collect and use each type.
+
+We do our best to not collect any Personal Information from Taler Wallet
+users. We believe that the Taler Wallet never transmits personal information
+to our services without at least clear implied consent, and we only process
+and retain information with a strict business need. That being said, when
+using our Services, we inherently have to collect the following information:
+
+ * Bank account details necessary when receiving funds from you to top-up your wallet or to transfer funds to you when you are being paid via Taler. At the current experimental stage, only the pseudonym and password you entered in the bank demonstrator is stored.
+
+ * The amounts being withdrawn or deposited, with associated unique transaction identifiers and cryptographic signatures authorizing the transaction. Note that for purchases, we cannot identify the buyer from the collected data, so when you spend money, we only receive non-personal information.
+
+ * When you contact us. We may collect certain information if you choose to contact us, for example to report a bug or other error with the Taler Wallet. This may include contact information such as your name, email address or phone number depending on the method you choose to contact us.
+
+
+How we collect and process information
+--------------------------------------
+
+We may process your information for the following reasons:
+
+ * to transfer money as specified by our users (Taler transactions);
+ * to assist government entities in linking income to the underlying contract
+ * to support you using the Taler Wallet or to improve our Services
+
+
+How we share and use the information we gather
+----------------------------------------------
+
+We may share your Personal Data or other information about you only if you are
+a merchant receiving income, with your bank, to the degree necessary to
+execute the payment.
+
+We retain Personal Data to transfer funds to the accounts designated by our
+users. We may retain Personal Data only for as long as mandated by law and
+required for the wire transfers.
+
+We primarily use the limited information we receive directly from you to
+enhance the Taler Wallet. Some ways we may use your Personal Information are
+to: Contact you when necessary to respond to your comments, answer your
+questions, or obtain additional information on issues related to bugs or
+errors with the Taler Wallet that you reported.
+
+
+Agents or third party partners
+------------------------------
+
+We may provide your Personal Information to our employees, contractors,
+agents, service providers, and designees (“Agents”) to enable them to perform
+certain services for us exclusively, including: improvement and maintenance of
+our software and Services. By accepting this Privacy Policy, as outlined
+above, you consent to any such transfer.
+
+
+Protection of us and others
+---------------------------
+
+We reserve the right to access, read, preserve, and disclose any information
+that we reasonably believe is necessary to comply with the law or a court
+order.
+
+
+What personal information can I access or change?
+-------------------------------------------------
+
+You can request access to the information we have collected from you. You can
+do this by contacting us at privacy@taler-systems.net. We will make sure to
+provide you with a copy of the data we process about you. To comply with your
+request, we may ask you to verify your identity. We will fulfill your request
+by sending your copy electronically. For any subsequent access request, we may
+charge you with an administrative fee. If you believe that the information we
+have collected is incorrect, you are welcome to contact us so we can update it
+and keep your data accurate. Any data that is no longer needed for purposes
+specified in the “How We Use the Information We Gather” section will be
+deleted after ninety (90) days.
+
+
+Data retention
+--------------
+
+If you uninstall the Taler Wallet mobile applications from your device, or
+request that your information be deleted, we still may retain some information
+that you have provided to us to maintain the Taler Wallet or to comply with
+relevant laws.
+
+
+Data security
+-------------
+
+We are committed to making sure your information is protected. We employ
+several physical and electronic safeguards to keep your information safe,
+including encrypted user passwords, two factor verification and authentication
+on passwords where possible, and securing connections with industry standard
+transport layer security. You are also welcome to contact us using GnuPG
+encrypted e-mail. Even with all these precautions, we cannot fully guarantee
+against the access, disclosure, alteration, or deletion of data through
+events, including but not limited to hardware or software failure or
+unauthorized use. Any information that you provide to us is done so entirely
+at your own risk.
+
+
+Changes and updates to privacy policy
+-------------------------------------
+
+We reserve the right to update and revise this privacy policy at any time. We
+occasionally review this Privacy Policy to make sure it complies with
+applicable laws and conforms to changes in our business. We may need to update
+this Privacy Policy, and we reserve the right to do so at any time. If we do
+revise this Privacy Policy, we will update the “Effective Date” at the bottom
+of this page so that you can tell if it has changed since your last visit. As
+we generally do not collect contact information and also do not track your
+visits, we will not be able to notify you directly. However, the Taler Wallet
+may inform you about a change in the privacy policy once it detects that the
+policy has changed. Please review this Privacy Policy regularly to ensure that
+you are aware of its terms. Any use of our Services after an amendment to our
+Privacy Policy constitutes your acceptance to the revised or amended
+agreement.
+
+
+International users and visitors
+--------------------------------
+
+Our Services are hosted in Switzerland. If you are a user accessing the
+Services from the European Union, Asia, US, or any other region with laws or
+regulations governing personal data collection, use, and disclosure that
+differ from Swiss laws, please be advised that through your continued use of
+the Services, which is governed by Swiss law, you are transferring your
+Personal Information to Switzerland and you consent to that transfer.
+
+
+Questions
+---------
+
+Please contact us at privacy@taler-systems.net if you have questions about our
+privacy practices that are not addressed in this Privacy Statement.
diff --git a/contrib/update-pp.sh b/contrib/update-pp.sh
new file mode 100755
index 00000000..db31ba18
--- /dev/null
+++ b/contrib/update-pp.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+# This file is in the public domain
+
+# Should be called with the list of languages to generate, i.e.
+# $ ./update-pp.sh en de fr it
+
+# Error checking on
+set -eu
+echo "Generating PP for ETag $VERSION"
+
+rm -f sphinx.log sphinx.err
+# We process inputs using Makefile in tos/ directory
+cd pp
+for l in $@
+do
+ mkdir -p $l
+ echo Generating PP for language $l
+ # 'f' is for the supported formats, note that the 'make' target
+ # MUST match the file extension.
+ for f in html txt pdf epub xml
+ do
+ rm -rf _build
+ echo " Generating format $f"
+ make -e SPHINXOPTS="-D language='$l'" $f >>sphinx.log 2>>sphinx.err < /dev/null
+ mv _build/$f/pp.$f $l/${VERSION}.$f
+ done
+done
+cd ..
--
cgit v1.2.3
From 3d90810f0092476ba4d37c135c430b11783da373 Mon Sep 17 00:00:00 2001
From: Christian Grothoff
Date: Fri, 7 Feb 2020 01:00:44 +0100
Subject: fix typo
---
contrib/tos/en/0.epub | Bin 16631 -> 16629 bytes
contrib/tos/en/0.html | 4 ++--
contrib/tos/en/0.pdf | Bin 99867 -> 99859 bytes
contrib/tos/en/0.txt | 2 +-
contrib/tos/en/0.xml | 4 ++--
contrib/tos/locale/de/LC_MESSAGES/tos.po | 7 +++++--
contrib/tos/tos.rst | 2 +-
7 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/contrib/tos/en/0.epub b/contrib/tos/en/0.epub
index a6c7860b..5acb8dfc 100644
Binary files a/contrib/tos/en/0.epub and b/contrib/tos/en/0.epub differ
diff --git a/contrib/tos/en/0.html b/contrib/tos/en/0.html
index 2c8000c3..07a3ab40 100644
--- a/contrib/tos/en/0.html
+++ b/contrib/tos/en/0.html
@@ -238,8 +238,8 @@ implied warranties, so the foregoing disclaimers may not apply to you. This
paragraph gives you specific legal rights and you may also have other legal
rights that vary from state to state.
-
To the extent permitted by applicable law, you agree to defend, indemnify, and
hold harmless the Taler Parties from and against any and all claims, damages,
obligations, losses, liabilities, costs or debt, and expenses (including, but
diff --git a/contrib/tos/en/0.pdf b/contrib/tos/en/0.pdf
index 972b91b9..ce3f013c 100644
Binary files a/contrib/tos/en/0.pdf and b/contrib/tos/en/0.pdf differ
diff --git a/contrib/tos/en/0.txt b/contrib/tos/en/0.txt
index 9b512f01..ce0893fa 100644
--- a/contrib/tos/en/0.txt
+++ b/contrib/tos/en/0.txt
@@ -268,7 +268,7 @@ you. This paragraph gives you specific legal rights and you may also
have other legal rights that vary from state to state.
-Indemntiy
+Indemnity
=========
To the extent permitted by applicable law, you agree to defend,
diff --git a/contrib/tos/en/0.xml b/contrib/tos/en/0.xml
index 45871ead..75974dc4 100644
--- a/contrib/tos/en/0.xml
+++ b/contrib/tos/en/0.xml
@@ -253,8 +253,8 @@
paragraph gives you specific legal rights and you may also have other legal
rights that vary from state to state.
-
- Indemntiy
+
+ IndemnityTo the extent permitted by applicable law, you agree to defend, indemnify, and
hold harmless the Taler Parties from and against any and all claims, damages,
obligations, losses, liabilities, costs or debt, and expenses (including, but
diff --git a/contrib/tos/locale/de/LC_MESSAGES/tos.po b/contrib/tos/locale/de/LC_MESSAGES/tos.po
index 4644a5c8..21aa9c88 100644
--- a/contrib/tos/locale/de/LC_MESSAGES/tos.po
+++ b/contrib/tos/locale/de/LC_MESSAGES/tos.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: tos 0\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-02-07 00:35+0100\n"
+"POT-Creation-Date: 2020-02-07 01:00+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -368,7 +368,7 @@ msgid ""
msgstr ""
#: ../../tos.rst:229
-msgid "Indemntiy"
+msgid "Indemnity"
msgstr ""
#: ../../tos.rst:231
@@ -512,3 +512,6 @@ msgid ""
"a message on our contact page at legal@taler-systems.com."
msgstr ""
+#~ msgid "Indemntiy"
+#~ msgstr ""
+
diff --git a/contrib/tos/tos.rst b/contrib/tos/tos.rst
index aff01001..2ef5c2c2 100644
--- a/contrib/tos/tos.rst
+++ b/contrib/tos/tos.rst
@@ -225,7 +225,7 @@ implied warranties, so the foregoing disclaimers may not apply to you. This
paragraph gives you specific legal rights and you may also have other legal
rights that vary from state to state.
-Indemntiy
+Indemnity
---------
To the extent permitted by applicable law, you agree to defend, indemnify, and
--
cgit v1.2.3
From 964cd7a459763a3ddc21f2b32f81a1dad5b7a4ce Mon Sep 17 00:00:00 2001
From: Christian Grothoff
Date: Sat, 8 Feb 2020 17:41:27 +0100
Subject: adding test for #6054 (duplicate WTID)
---
src/auditor/test-auditor.sh | 43 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/src/auditor/test-auditor.sh b/src/auditor/test-auditor.sh
index 00ed0523..5f7d0c8c 100755
--- a/src/auditor/test-auditor.sh
+++ b/src/auditor/test-auditor.sh
@@ -1473,6 +1473,49 @@ echo "UPDATE deposits SET wire='$OLD_WIRE' WHERE deposit_serial_id=${SERIAL}" |
}
+# Test for duplicate wire transfer subject
+function test_27() {
+echo "===========27: duplicate WTID 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-wire-auditor.c)
+if [ $DATABASE_AGE -gt 3600 ]
+then
+
+ pre_audit aggregator
+
+ # Obtain data to duplicate.
+ ID=`echo "SELECT id FROM app_banktransaction WHERE debit_account_id=2 LIMIT 1" | psql $DB -Aqt`
+ WTID=`echo "SELECT subject FROM app_banktransaction WHERE debit_account_id=2 LIMIT 1" | psql $DB -Aqt`
+ echo "INSERT INTO app_banktransaction (amount,subject,date,credit_account_id,debit_account_id,cancelled) VALUES ('TESTKUDOS:1','$WTID',NOW(),12,2,'f')" | psql -Aqt $DB
+
+ audit_only
+ post_audit
+
+ echo -n "Testing inconsistency detection... "
+
+ AMOUNT=`jq -r .wire_format_inconsistencies[0].amount < test-wire-audit.json`
+ if test "${AMOUNT}" != "TESTKUDOS:1"
+ then
+ exit_fail "Amount wrong, got ${AMOUNT}"
+ fi
+
+ AMOUNT=`jq -r .total_wire_format_amount < test-wire-audit.json`
+ if test "${AMOUNT}" != "TESTKUDOS:1"
+ then
+ exit_fail "Wrong total wire format amount, got $AMOUNT"
+ fi
+
+ # cannot easily undo aggregator, hence full reload
+ full_reload
+else
+ echo "Test skipped (database too new)"
+fi
+
+}
# **************************************************
--
cgit v1.2.3
From db46491db994349a79cddae9fbfd6fd15ad16127 Mon Sep 17 00:00:00 2001
From: Christian Grothoff
Date: Sat, 8 Feb 2020 17:49:56 +0100
Subject: fix uninitialized session
---
src/auditor/taler-auditor-httpd_deposit-confirmation.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation.c b/src/auditor/taler-auditor-httpd_deposit-confirmation.c
index 87b1a26f..ab233ebc 100644
--- a/src/auditor/taler-auditor-httpd_deposit-confirmation.c
+++ b/src/auditor/taler-auditor-httpd_deposit-confirmation.c
@@ -101,6 +101,15 @@ verify_and_execute_deposit_confirmation (struct MHD_Connection *connection,
&h);
GNUNET_assert (0 == pthread_mutex_unlock (&lock));
+ session = TAH_plugin->get_session (TAH_plugin->cls);
+ if (NULL == session)
+ {
+ GNUNET_break (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_DB_SETUP_FAILED,
+ "failed to establish session with database");
+ }
if (! cached)
{
/* Not in cache, need to verify the signature, persist it, and possibly cache it */
@@ -117,15 +126,6 @@ verify_and_execute_deposit_confirmation (struct MHD_Connection *connection,
"master_sig");
}
- session = TAH_plugin->get_session (TAH_plugin->cls);
- if (NULL == session)
- {
- GNUNET_break (0);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_DB_SETUP_FAILED,
- "failed to establish session with database");
- }
/* execute transaction */
qs = TAH_plugin->insert_exchange_signkey (TAH_plugin->cls,
session,
--
cgit v1.2.3
From 37c29157691715c3861b473b98444534fb33cbb2 Mon Sep 17 00:00:00 2001
From: Christian Grothoff
Date: Sat, 8 Feb 2020 17:55:22 +0100
Subject: do not report missing reserve closures of amount 0.0
---
src/auditor/taler-wire-auditor.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/src/auditor/taler-wire-auditor.c b/src/auditor/taler-wire-auditor.c
index 5a68f165..92664fb8 100644
--- a/src/auditor/taler-wire-auditor.c
+++ b/src/auditor/taler-wire-auditor.c
@@ -704,13 +704,15 @@ check_pending_rc (void *cls,
TALER_amount_add (&total_closure_amount_lag,
&total_closure_amount_lag,
&rc->amount));
- report (report_closure_lags,
- json_pack ("{s:I, s:o, s:o, s:o, s:s}",
- "row", (json_int_t) rc->rowid,
- "amount", TALER_JSON_from_amount (&rc->amount),
- "deadline", json_from_time_abs (rc->execution_date),
- "wtid", GNUNET_JSON_from_data_auto (&rc->wtid),
- "account", rc->receiver_account));
+ if ( (0 != rc->amount.value) ||
+ (0 != rc->amount.fraction) )
+ report (report_closure_lags,
+ json_pack ("{s:I, s:o, s:o, s:o, s:s}",
+ "row", (json_int_t) rc->rowid,
+ "amount", TALER_JSON_from_amount (&rc->amount),
+ "deadline", json_from_time_abs (rc->execution_date),
+ "wtid", GNUNET_JSON_from_data_auto (&rc->wtid),
+ "account", rc->receiver_account));
pp.last_reserve_close_uuid
= GNUNET_MIN (pp.last_reserve_close_uuid,
rc->rowid);
--
cgit v1.2.3
From f70596ff4c93a1906533fd488bf5fed1801eeb99 Mon Sep 17 00:00:00 2001
From: Christian Grothoff
Date: Sat, 8 Feb 2020 18:38:15 +0100
Subject: adding UNIX socket and restart tests (#5309)
---
contrib/taler-exchange-revoke | 2 +-
src/exchange/Makefile.am | 4 +-
src/exchange/test_taler_exchange_httpd_restart.sh | 117 ++++++++++++++++++
src/exchange/test_taler_exchange_unix.conf | 137 ++++++++++++++++++++++
4 files changed, 258 insertions(+), 2 deletions(-)
create mode 100755 src/exchange/test_taler_exchange_httpd_restart.sh
create mode 100644 src/exchange/test_taler_exchange_unix.conf
diff --git a/contrib/taler-exchange-revoke b/contrib/taler-exchange-revoke
index 8ce0e878..8e4bc6ed 100755
--- a/contrib/taler-exchange-revoke
+++ b/contrib/taler-exchange-revoke
@@ -19,6 +19,6 @@ fi
taler-exchange-keyup -c $1 -r $2
EXCHANGE_PID=`ps x | grep taler-exchange-httpd | awk '{print $1}'`
-kill -HUP $EXCHANGE_PID
+kill -SIGUSR1 $EXCHANGE_PID
exit 0
diff --git a/src/exchange/Makefile.am b/src/exchange/Makefile.am
index 50eb545b..cf9f984d 100644
--- a/src/exchange/Makefile.am
+++ b/src/exchange/Makefile.am
@@ -83,7 +83,8 @@ taler_exchange_httpd_LDADD = \
AM_TESTS_ENVIRONMENT=export TALER_PREFIX=$${TALER_PREFIX:-@libdir@};export PATH=$${TALER_PREFIX:-@prefix@}/bin:$$PATH;
check_SCRIPTS = \
- test_taler_exchange_httpd.sh
+ test_taler_exchange_httpd.sh \
+ test_taler_exchange_httpd_restart.sh
if HAVE_EXPENSIVE_TESTS
check_SCRIPTS += \
test_taler_exchange_httpd_afl.sh
@@ -97,6 +98,7 @@ TESTS = \
EXTRA_DIST = \
test_taler_exchange_httpd_home/.local/share/taler/exchange/offline-keys/master.priv \
test_taler_exchange_httpd.conf \
+ test_taler_exchange_unix.conf \
test_taler_exchange_httpd.get \
test_taler_exchange_httpd.post \
exchange.conf \
diff --git a/src/exchange/test_taler_exchange_httpd_restart.sh b/src/exchange/test_taler_exchange_httpd_restart.sh
new file mode 100755
index 00000000..81ac0455
--- /dev/null
+++ b/src/exchange/test_taler_exchange_httpd_restart.sh
@@ -0,0 +1,117 @@
+#!/bin/bash
+#
+# This file is part of TALER
+# Copyright (C) 2020 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, If not, see
+#
+#
+# This script launches an exchange (binding to a UNIX domain socket) and then
+# restarts it in various ways (SIGHUP to re-read configuration, and SIGUSR1 to
+# re-spawn a new binary). Basically, the goal is to make sure that the HTTP
+# server survives these less common operations.
+#
+#
+set -eu
+
+# Exit, with status code "skip" (no 'real' failure)
+function exit_skip() {
+ echo $1
+ exit 77
+}
+
+# Exit, with error message (hard failure)
+function exit_fail() {
+ echo $1
+ kill `jobs -p` >/dev/null 2>/dev/null || true
+ wait
+ exit 1
+}
+
+echo -n "Testing for curl"
+curl --version >/dev/null /dev/null || exit 1
+# Run Exchange HTTPD (in background)
+$PREFIX taler-exchange-httpd -c test_taler_exchange_unix.conf -i 2> test-exchange.log &
+
+# Where should we be bound to?
+UNIXPATH=`taler-config -s exchange -f -o UNIXPATH`
+
+# Give HTTP time to start
+
+for n in `seq 1 100`
+do
+ echo -n "."
+ sleep 0.1
+ OK=1
+ curl --unix-socket "${UNIXPATH}" "http://ignored/" >/dev/null 2> /dev/null && break
+ OK=0
+done
+if [ 1 != $OK ]
+then
+ echo "Failed to launch exchange"
+ kill -TERM $!
+ wait $!
+ echo Process status: $?
+ exit 77
+fi
+echo " DONE"
+
+# Finally run test...
+echo -n "Reloading keys ..."
+kill -SIGUSR1 $!
+sleep 1
+curl --unix-socket "${UNIXPATH}" "http://ignored/" >/dev/null 2> /dev/null || exit_fail "SIGUSR1 killed HTTP service"
+echo " DONE"
+
+# Finally run test...
+echo -n "Restarting program ..."
+kill -SIGHUP $!
+sleep 1
+curl --unix-socket "${UNIXPATH}" "http://ignored/" >/dev/null 2> /dev/null || exit_fail "SIGHUP killed HTTP service"
+echo " DONE"
+
+echo -n "Waiting for parent to die ..."
+wait $!
+echo " DONE"
+
+echo -n "Testing child still alive ..."
+curl --unix-socket "${UNIXPATH}" "http://ignored/" >/dev/null 2> /dev/null || exit_fail "SIGHUP killed HTTP service"
+echo " DONE"
+
+
+echo -n "Killing grandchild ..."
+CPID=`ps x | grep taler-exchange-httpd | grep -v grep | awk '{print $1}'`
+kill -TERM $CPID
+while true
+do
+ ps x | grep -v grep | grep taler-exchange-httpd > /dev/null || break
+done
+echo " DONE"
+
+# Return status code from exchange for this script
+exit 0
diff --git a/src/exchange/test_taler_exchange_unix.conf b/src/exchange/test_taler_exchange_unix.conf
new file mode 100644
index 00000000..d41df9ab
--- /dev/null
+++ b/src/exchange/test_taler_exchange_unix.conf
@@ -0,0 +1,137 @@
+[PATHS]
+# Persistant data storage for the testcase
+TALER_TEST_HOME = test_taler_exchange_httpd_home/
+
+[taler]
+# Currency supported by the exchange (can only be one)
+CURRENCY = EUR
+CURRENCY_ROUND_UNIT = EUR:0.01
+
+[exchange]
+
+# Directory with our terms of service.
+TERMS_DIR = ../../contrib/tos
+
+# Etag / filename for the terms of service.
+TERMS_ETAG = 0
+
+
+# Directory with our privacy policy.
+PRIVACY_DIR = ../../contrib/pp
+
+# Etag / filename for the privacy policy.
+PRIVACY_ETAG = 0
+
+# MAX_REQUESTS = 2
+# how long is one signkey valid?
+SIGNKEY_DURATION = 4 weeks
+
+# how long are the signatures with the signkey valid?
+LEGAL_DURATION = 2 years
+
+# how long do we generate denomination and signing keys
+# ahead of time?
+LOOKAHEAD_SIGN = 32 weeks 1 day
+
+# how long do we provide to clients denomination and signing keys
+# ahead of time?
+LOOKAHEAD_PROVIDE = 4 weeks 1 day
+
+# HTTP port the exchange listens to (we want to use UNIX domain sockets,
+# so we use a port that just won't work on GNU/Linux without root rights)
+PORT = 999
+
+# Here we say we want to use a UNIX domain socket (to test that logic).
+SERVE = unix
+
+# Master public key used to sign the exchange's various keys
+MASTER_PUBLIC_KEY = 98NJW3CQHZQGQXTY3K85K531XKPAPAVV4Q5V8PYYRR00NJGZWNVG
+
+# How to access our database
+DB = postgres
+
+
+[exchangedb]
+# After how long do we close idle reserves? The exchange
+# and the auditor must agree on this value. We currently
+# expect it to be globally defined for the whole system,
+# as there is no way for wallets to query this value. Thus,
+# it is only configurable for testing, and should be treated
+# as constant in production.
+IDLE_RESERVE_EXPIRATION_TIME = 4 weeks
+
+
+[exchangedb-postgres]
+CONFIG = "postgres:///talercheck"
+
+[exchange-account-1]
+PAYTO_URI = "payto://x-taler-bank/localhost:8082/3"
+WIRE_RESPONSE = ${TALER_CONFIG_HOME}/account-1.json
+ENABLE_DEBIT = YES
+ENABLE_CREDIT = YES
+TALER_BANK_AUTH_METHOD = NONE
+
+
+# Wire fees are specified by wire method
+[fees-x-taler-bank]
+# Fees for the forseeable future...
+# If you see this after 2018, update to match the next 10 years...
+WIRE-FEE-2018 = EUR:0.01
+WIRE-FEE-2019 = EUR:0.01
+WIRE-FEE-2020 = EUR:0.01
+WIRE-FEE-2021 = EUR:0.01
+WIRE-FEE-2022 = EUR:0.01
+WIRE-FEE-2023 = EUR:0.01
+WIRE-FEE-2024 = EUR:0.01
+WIRE-FEE-2025 = EUR:0.01
+WIRE-FEE-2026 = EUR:0.01
+WIRE-FEE-2027 = EUR:0.01
+
+CLOSING-FEE-2018 = EUR:0.01
+CLOSING-FEE-2019 = EUR:0.01
+CLOSING-FEE-2020 = EUR:0.01
+CLOSING-FEE-2021 = EUR:0.01
+CLOSING-FEE-2022 = EUR:0.01
+CLOSING-FEE-2023 = EUR:0.01
+CLOSING-FEE-2024 = EUR:0.01
+CLOSING-FEE-2025 = EUR:0.01
+CLOSING-FEE-2026 = EUR:0.01
+CLOSING-FEE-2027 = EUR:0.01
+
+
+# Coins for the tests.
+[coin_eur_ct_1]
+value = EUR:0.01
+duration_overlap = 5 minutes
+duration_withdraw = 7 days
+duration_spend = 2 years
+duration_legal = 3 years
+fee_withdraw = EUR:0.00
+fee_deposit = EUR:0.00
+fee_refresh = EUR:0.01
+fee_refund = EUR:0.01
+rsa_keysize = 1024
+
+[coin_eur_ct_10]
+value = EUR:0.10
+duration_overlap = 5 minutes
+duration_withdraw = 7 days
+duration_spend = 2 years
+duration_legal = 3 years
+fee_withdraw = EUR:0.01
+fee_deposit = EUR:0.01
+fee_refresh = EUR:0.03
+fee_refund = EUR:0.01
+rsa_keysize = 1024
+
+[coin_eur_1]
+value = EUR:1
+duration_overlap = 5 minutes
+duration_withdraw = 7 days
+duration_spend = 2 years
+duration_legal = 3 years
+fee_withdraw = EUR:0.01
+fee_deposit = EUR:0.01
+fee_refresh = EUR:0.03
+fee_refund = EUR:0.01
+rsa_keysize = 1024
--
cgit v1.2.3
From 001f1552089fbd1e7fea540d2561c79bab2dfbac Mon Sep 17 00:00:00 2001
From: Christian Grothoff
Date: Sat, 8 Feb 2020 19:06:19 +0100
Subject: make script a bit nicer
---
src/exchange/test_taler_exchange_httpd_restart.sh | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/src/exchange/test_taler_exchange_httpd_restart.sh b/src/exchange/test_taler_exchange_httpd_restart.sh
index 81ac0455..f7d7a305 100755
--- a/src/exchange/test_taler_exchange_httpd_restart.sh
+++ b/src/exchange/test_taler_exchange_httpd_restart.sh
@@ -49,7 +49,7 @@ unset XDG_CONFIG_HOME
echo -n "Launching exchange ..."
PREFIX=
# Uncomment this line to run with valgrind...
-# PREFIX="valgrind --leak-check=yes --track-fds=yes --error-exitcode=1 --log-file=valgrind.%p"
+# PREFIX="valgrind --trace-children=yes --leak-check=yes --track-fds=yes --error-exitcode=1 --log-file=valgrind.%p"
# Setup keys.
taler-exchange-keyup -c test_taler_exchange_unix.conf || exit 1
@@ -73,11 +73,7 @@ do
done
if [ 1 != $OK ]
then
- echo "Failed to launch exchange"
- kill -TERM $!
- wait $!
- echo Process status: $?
- exit 77
+ exit_fail "Failed to launch exchange"
fi
echo " DONE"
@@ -110,6 +106,7 @@ kill -TERM $CPID
while true
do
ps x | grep -v grep | grep taler-exchange-httpd > /dev/null || break
+ sleep 0.1
done
echo " DONE"
--
cgit v1.2.3
From ae5583f04434cf39a5ae7a6f623bfc76322f9eb3 Mon Sep 17 00:00:00 2001
From: Christian Grothoff
Date: Sun, 9 Feb 2020 15:53:28 +0100
Subject: avoid duping configuration, start to use PQ_connect_with_cfg
---
src/auditordb/auditordb_plugin.c | 5 +----
src/auditordb/plugin_auditordb_postgres.c | 2 +-
src/exchangedb/exchangedb_plugin.c | 6 ++----
src/exchangedb/plugin_exchangedb_postgres.c | 17 ++++++++++++-----
4 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/src/auditordb/auditordb_plugin.c b/src/auditordb/auditordb_plugin.c
index 19717fe8..d04e8815 100644
--- a/src/auditordb/auditordb_plugin.c
+++ b/src/auditordb/auditordb_plugin.c
@@ -35,7 +35,6 @@ TALER_AUDITORDB_plugin_load (const struct GNUNET_CONFIGURATION_Handle *cfg)
{
char *plugin_name;
char *lib_name;
- struct GNUNET_CONFIGURATION_Handle *cfg_dup;
struct TALER_AUDITORDB_Plugin *plugin;
if (GNUNET_SYSERR ==
@@ -53,14 +52,12 @@ TALER_AUDITORDB_plugin_load (const struct GNUNET_CONFIGURATION_Handle *cfg)
"libtaler_plugin_auditordb_%s",
plugin_name);
GNUNET_free (plugin_name);
- cfg_dup = GNUNET_CONFIGURATION_dup (cfg);
plugin = GNUNET_PLUGIN_load (lib_name,
- cfg_dup);
+ (void *) cfg);
if (NULL != plugin)
plugin->library_name = lib_name;
else
GNUNET_free (lib_name);
- GNUNET_CONFIGURATION_destroy (cfg_dup);
return plugin;
}
diff --git a/src/auditordb/plugin_auditordb_postgres.c b/src/auditordb/plugin_auditordb_postgres.c
index 30db303b..08d24fd7 100644
--- a/src/auditordb/plugin_auditordb_postgres.c
+++ b/src/auditordb/plugin_auditordb_postgres.c
@@ -3244,7 +3244,7 @@ postgres_get_predicted_balance (void *cls,
void *
libtaler_plugin_auditordb_postgres_init (void *cls)
{
- struct GNUNET_CONFIGURATION_Handle *cfg = cls;
+ const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
struct PostgresClosure *pg;
struct TALER_AUDITORDB_Plugin *plugin;
const char *ec;
diff --git a/src/exchangedb/exchangedb_plugin.c b/src/exchangedb/exchangedb_plugin.c
index 8e61f860..f4c2eea9 100644
--- a/src/exchangedb/exchangedb_plugin.c
+++ b/src/exchangedb/exchangedb_plugin.c
@@ -35,7 +35,6 @@ TALER_EXCHANGEDB_plugin_load (const struct GNUNET_CONFIGURATION_Handle *cfg)
{
char *plugin_name;
char *lib_name;
- struct GNUNET_CONFIGURATION_Handle *cfg_dup;
struct TALER_EXCHANGEDB_Plugin *plugin;
if (GNUNET_SYSERR ==
@@ -53,13 +52,12 @@ TALER_EXCHANGEDB_plugin_load (const struct GNUNET_CONFIGURATION_Handle *cfg)
"libtaler_plugin_exchangedb_%s",
plugin_name);
GNUNET_free (plugin_name);
- cfg_dup = GNUNET_CONFIGURATION_dup (cfg);
- plugin = GNUNET_PLUGIN_load (lib_name, cfg_dup);
+ plugin = GNUNET_PLUGIN_load (lib_name,
+ (void *) cfg);
if (NULL != plugin)
plugin->library_name = lib_name;
else
GNUNET_free (lib_name);
- GNUNET_CONFIGURATION_destroy (cfg_dup);
return plugin;
}
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index 4d0b1bb6..fe0021fa 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -108,6 +108,11 @@ struct PostgresClosure
*/
pthread_key_t db_conn_threadlocal;
+ /**
+ * Our configuration.
+ */
+ const struct GNUNET_CONFIGURATION_Handle *cfg;
+
/**
* Database connection string, as read from
* the configuration.
@@ -187,10 +192,11 @@ postgres_create_tables (void *cls)
struct PostgresClosure *pc = cls;
struct GNUNET_PQ_Context *conn;
- conn = GNUNET_PQ_connect (pc->connection_cfg_str,
- pc->sql_dir,
- NULL,
- NULL);
+ conn = GNUNET_PQ_connect_with_cfg (pc->cfg,
+ "exchangedb-postgres",
+ "",
+ NULL,
+ NULL);
if (NULL == conn)
return GNUNET_SYSERR;
GNUNET_PQ_disconnect (conn);
@@ -7212,12 +7218,13 @@ postgres_select_deposits_missing_wire (void *cls,
void *
libtaler_plugin_exchangedb_postgres_init (void *cls)
{
- struct GNUNET_CONFIGURATION_Handle *cfg = cls;
+ const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
struct PostgresClosure *pg;
struct TALER_EXCHANGEDB_Plugin *plugin;
const char *ec;
pg = GNUNET_new (struct PostgresClosure);
+ pg->cfg = cfg;
pg->main_self = pthread_self (); /* loaded while single-threaded! */
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_filename (cfg,
--
cgit v1.2.3
From cdaf1ce69b5fb56f09bbdc00942b03f039710614 Mon Sep 17 00:00:00 2001
From: Christian Grothoff
Date: Sun, 9 Feb 2020 16:34:40 +0100
Subject: rename SQL files to make filenames consistent with versioning name
---
src/auditordb/0000.sql | 293 ----------------------
src/auditordb/0001.sql | 239 ------------------
src/auditordb/Makefile.am | 4 +-
src/auditordb/auditor-0000.sql | 293 ++++++++++++++++++++++
src/auditordb/auditor-0001.sql | 239 ++++++++++++++++++
src/auditordb/plugin_auditordb_postgres.c | 93 ++-----
src/exchangedb/0000.sql | 293 ----------------------
src/exchangedb/0001.sql | 368 ----------------------------
src/exchangedb/Makefile.am | 4 +-
src/exchangedb/exchange-0000.sql | 293 ++++++++++++++++++++++
src/exchangedb/exchange-0001.sql | 368 ++++++++++++++++++++++++++++
src/exchangedb/plugin_exchangedb_postgres.c | 68 ++---
12 files changed, 1238 insertions(+), 1317 deletions(-)
delete mode 100644 src/auditordb/0000.sql
delete mode 100644 src/auditordb/0001.sql
create mode 100644 src/auditordb/auditor-0000.sql
create mode 100644 src/auditordb/auditor-0001.sql
delete mode 100644 src/exchangedb/0000.sql
delete mode 100644 src/exchangedb/0001.sql
create mode 100644 src/exchangedb/exchange-0000.sql
create mode 100644 src/exchangedb/exchange-0001.sql
diff --git a/src/auditordb/0000.sql b/src/auditordb/0000.sql
deleted file mode 100644
index 1483e201..00000000
--- a/src/auditordb/0000.sql
+++ /dev/null
@@ -1,293 +0,0 @@
--- LICENSE AND COPYRIGHT
---
--- Copyright (C) 2010 Hubert depesz Lubaczewski
---
--- This program is distributed under the (Revised) BSD License:
--- L
---
--- Redistribution and use in source and binary forms, with or without
--- modification, are permitted provided that the following conditions
--- are met:
---
--- * Redistributions of source code must retain the above copyright
--- notice, this list of conditions and the following disclaimer.
---
--- * Redistributions in binary form must reproduce the above copyright
--- notice, this list of conditions and the following disclaimer in the
--- documentation and/or other materials provided with the distribution.
---
--- * Neither the name of Hubert depesz Lubaczewski's Organization
--- nor the names of its contributors may be used to endorse or
--- promote products derived from this software without specific
--- prior written permission.
---
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
--- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
--- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
--- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
--- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
--- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
--- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
--- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
--- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---
--- Code origin: https://gitlab.com/depesz/Versioning/blob/master/install.versioning.sql
---
---
--- # NAME
---
--- **Versioning** - simplistic take on tracking and applying changes to databases.
---
--- # DESCRIPTION
---
--- This project strives to provide simple way to manage changes to
--- database.
---
--- Instead of making changes on development server, then finding
--- differences between production and development, deciding which ones
--- should be installed on production, and finding a way to install them -
--- you start with writing diffs themselves!
---
--- # INSTALLATION
---
--- To install versioning simply run install.versioning.sql in your database
--- (all of them: production, stage, test, devel, ...).
---
--- # USAGE
---
--- In your files with patches to database, put whole logic in single
--- transaction, and use \_v.\* functions - usually \_v.register_patch() at
--- least to make sure everything is OK.
---
--- For example. Let's assume you have patch files:
---
--- ## 0001.sql:
---
--- ```
--- create table users (id serial primary key, username text);
--- ```
---
--- ## 0002.sql:
---
--- ```
--- insert into users (username) values ('depesz');
--- ```
--- To change it to use versioning you would change the files, to this
--- state:
---
--- 0000.sql:
---
--- ```
--- BEGIN;
--- select _v.register_patch('000-base', NULL, NULL);
--- create table users (id serial primary key, username text);
--- COMMIT;
--- ```
---
--- ## 0002.sql:
---
--- ```
--- BEGIN;
--- select _v.register_patch('001-users', ARRAY['000-base'], NULL);
--- insert into users (username) values ('depesz');
--- COMMIT;
--- ```
---
--- This will make sure that patch 001-users can only be applied after
--- 000-base.
---
--- # AVAILABLE FUNCTIONS
---
--- ## \_v.register_patch( TEXT )
---
--- Registers named patch, or dies if it is already registered.
---
--- Returns integer which is id of patch in \_v.patches table - only if it
--- succeeded.
---
--- ## \_v.register_patch( TEXT, TEXT[] )
---
--- Same as \_v.register_patch( TEXT ), but checks is all given patches (given as
--- array in second argument) are already registered.
---
--- ## \_v.register_patch( TEXT, TEXT[], TEXT[] )
---
--- Same as \_v.register_patch( TEXT, TEXT[] ), but also checks if there are no conflicts with preexisting patches.
---
--- Third argument is array of names of patches that conflict with current one. So
--- if any of them is installed - register_patch will error out.
---
--- ## \_v.unregister_patch( TEXT )
---
--- Removes information about given patch from the versioning data.
---
--- It doesn't remove objects that were created by this patch - just removes
--- metainformation.
---
--- ## \_v.assert_user_is_superuser()
---
--- Make sure that current patch is being loaded by superuser.
---
--- If it's not - it will raise exception, and break transaction.
---
--- ## \_v.assert_user_is_not_superuser()
---
--- Make sure that current patch is not being loaded by superuser.
---
--- If it is - it will raise exception, and break transaction.
---
--- ## \_v.assert_user_is_one_of(TEXT, TEXT, ... )
---
--- Make sure that current patch is being loaded by one of listed users.
---
--- If ```current_user``` is not listed as one of arguments - function will raise
--- exception and break the transaction.
-
-BEGIN;
-
--- This file adds versioning support to database it will be loaded to.
--- It requires that PL/pgSQL is already loaded - will raise exception otherwise.
--- All versioning "stuff" (tables, functions) is in "_v" schema.
-
--- All functions are defined as 'RETURNS SETOF INT4' to be able to make them to RETURN literaly nothing (0 rows).
--- >> RETURNS VOID<< IS similar, but it still outputs "empty line" in psql when calling.
-CREATE SCHEMA IF NOT EXISTS _v;
-COMMENT ON SCHEMA _v IS 'Schema for versioning data and functionality.';
-
-CREATE TABLE IF NOT EXISTS _v.patches (
- patch_name TEXT PRIMARY KEY,
- applied_tsz TIMESTAMPTZ NOT NULL DEFAULT now(),
- applied_by TEXT NOT NULL,
- requires TEXT[],
- conflicts TEXT[]
-);
-COMMENT ON TABLE _v.patches IS 'Contains information about what patches are currently applied on database.';
-COMMENT ON COLUMN _v.patches.patch_name IS 'Name of patch, has to be unique for every patch.';
-COMMENT ON COLUMN _v.patches.applied_tsz IS 'When the patch was applied.';
-COMMENT ON COLUMN _v.patches.applied_by IS 'Who applied this patch (PostgreSQL username)';
-COMMENT ON COLUMN _v.patches.requires IS 'List of patches that are required for given patch.';
-COMMENT ON COLUMN _v.patches.conflicts IS 'List of patches that conflict with given patch.';
-
-CREATE OR REPLACE FUNCTION _v.register_patch( IN in_patch_name TEXT, IN in_requirements TEXT[], in_conflicts TEXT[], OUT versioning INT4 ) RETURNS setof INT4 AS $$
-DECLARE
- t_text TEXT;
- t_text_a TEXT[];
- i INT4;
-BEGIN
- -- Thanks to this we know only one patch will be applied at a time
- LOCK TABLE _v.patches IN EXCLUSIVE MODE;
-
- SELECT patch_name INTO t_text FROM _v.patches WHERE patch_name = in_patch_name;
- IF FOUND THEN
- RAISE EXCEPTION 'Patch % is already applied!', in_patch_name;
- END IF;
-
- t_text_a := ARRAY( SELECT patch_name FROM _v.patches WHERE patch_name = any( in_conflicts ) );
- IF array_upper( t_text_a, 1 ) IS NOT NULL THEN
- RAISE EXCEPTION 'Versioning patches conflict. Conflicting patche(s) installed: %.', array_to_string( t_text_a, ', ' );
- END IF;
-
- IF array_upper( in_requirements, 1 ) IS NOT NULL THEN
- t_text_a := '{}';
- FOR i IN array_lower( in_requirements, 1 ) .. array_upper( in_requirements, 1 ) LOOP
- SELECT patch_name INTO t_text FROM _v.patches WHERE patch_name = in_requirements[i];
- IF NOT FOUND THEN
- t_text_a := t_text_a || in_requirements[i];
- END IF;
- END LOOP;
- IF array_upper( t_text_a, 1 ) IS NOT NULL THEN
- RAISE EXCEPTION 'Missing prerequisite(s): %.', array_to_string( t_text_a, ', ' );
- END IF;
- END IF;
-
- INSERT INTO _v.patches (patch_name, applied_tsz, applied_by, requires, conflicts ) VALUES ( in_patch_name, now(), current_user, coalesce( in_requirements, '{}' ), coalesce( in_conflicts, '{}' ) );
- RETURN;
-END;
-$$ language plpgsql;
-COMMENT ON FUNCTION _v.register_patch( TEXT, TEXT[], TEXT[] ) IS 'Function to register patches in database. Raises exception if there are conflicts, prerequisites are not installed or the migration has already been installed.';
-
-CREATE OR REPLACE FUNCTION _v.register_patch( TEXT, TEXT[] ) RETURNS setof INT4 AS $$
- SELECT _v.register_patch( $1, $2, NULL );
-$$ language sql;
-COMMENT ON FUNCTION _v.register_patch( TEXT, TEXT[] ) IS 'Wrapper to allow registration of patches without conflicts.';
-CREATE OR REPLACE FUNCTION _v.register_patch( TEXT ) RETURNS setof INT4 AS $$
- SELECT _v.register_patch( $1, NULL, NULL );
-$$ language sql;
-COMMENT ON FUNCTION _v.register_patch( TEXT ) IS 'Wrapper to allow registration of patches without requirements and conflicts.';
-
-CREATE OR REPLACE FUNCTION _v.unregister_patch( IN in_patch_name TEXT, OUT versioning INT4 ) RETURNS setof INT4 AS $$
-DECLARE
- i INT4;
- t_text_a TEXT[];
-BEGIN
- -- Thanks to this we know only one patch will be applied at a time
- LOCK TABLE _v.patches IN EXCLUSIVE MODE;
-
- t_text_a := ARRAY( SELECT patch_name FROM _v.patches WHERE in_patch_name = ANY( requires ) );
- IF array_upper( t_text_a, 1 ) IS NOT NULL THEN
- RAISE EXCEPTION 'Cannot uninstall %, as it is required by: %.', in_patch_name, array_to_string( t_text_a, ', ' );
- END IF;
-
- DELETE FROM _v.patches WHERE patch_name = in_patch_name;
- GET DIAGNOSTICS i = ROW_COUNT;
- IF i < 1 THEN
- RAISE EXCEPTION 'Patch % is not installed, so it can''t be uninstalled!', in_patch_name;
- END IF;
-
- RETURN;
-END;
-$$ language plpgsql;
-COMMENT ON FUNCTION _v.unregister_patch( TEXT ) IS 'Function to unregister patches in database. Dies if the patch is not registered, or if unregistering it would break dependencies.';
-
-CREATE OR REPLACE FUNCTION _v.assert_patch_is_applied( IN in_patch_name TEXT ) RETURNS TEXT as $$
-DECLARE
- t_text TEXT;
-BEGIN
- SELECT patch_name INTO t_text FROM _v.patches WHERE patch_name = in_patch_name;
- IF NOT FOUND THEN
- RAISE EXCEPTION 'Patch % is not applied!', in_patch_name;
- END IF;
- RETURN format('Patch %s is applied.', in_patch_name);
-END;
-$$ language plpgsql;
-COMMENT ON FUNCTION _v.assert_patch_is_applied( TEXT ) IS 'Function that can be used to make sure that patch has been applied.';
-
-CREATE OR REPLACE FUNCTION _v.assert_user_is_superuser() RETURNS TEXT as $$
-DECLARE
- v_super bool;
-BEGIN
- SELECT usesuper INTO v_super FROM pg_user WHERE usename = current_user;
- IF v_super THEN
- RETURN 'assert_user_is_superuser: OK';
- END IF;
- RAISE EXCEPTION 'Current user is not superuser - cannot continue.';
-END;
-$$ language plpgsql;
-COMMENT ON FUNCTION _v.assert_user_is_superuser() IS 'Function that can be used to make sure that patch is being applied using superuser account.';
-
-CREATE OR REPLACE FUNCTION _v.assert_user_is_not_superuser() RETURNS TEXT as $$
-DECLARE
- v_super bool;
-BEGIN
- SELECT usesuper INTO v_super FROM pg_user WHERE usename = current_user;
- IF v_super THEN
- RAISE EXCEPTION 'Current user is superuser - cannot continue.';
- END IF;
- RETURN 'assert_user_is_not_superuser: OK';
-END;
-$$ language plpgsql;
-COMMENT ON FUNCTION _v.assert_user_is_not_superuser() IS 'Function that can be used to make sure that patch is being applied using normal (not superuser) account.';
-
-CREATE OR REPLACE FUNCTION _v.assert_user_is_one_of(VARIADIC p_acceptable_users TEXT[] ) RETURNS TEXT as $$
-DECLARE
-BEGIN
- IF current_user = any( p_acceptable_users ) THEN
- RETURN 'assert_user_is_one_of: OK';
- END IF;
- RAISE EXCEPTION 'User is not one of: % - cannot continue.', p_acceptable_users;
-END;
-$$ language plpgsql;
-COMMENT ON FUNCTION _v.assert_user_is_one_of(TEXT[]) IS 'Function that can be used to make sure that patch is being applied by one of defined users.';
-
-COMMIT;
diff --git a/src/auditordb/0001.sql b/src/auditordb/0001.sql
deleted file mode 100644
index 3e666519..00000000
--- a/src/auditordb/0001.sql
+++ /dev/null
@@ -1,239 +0,0 @@
---
--- This file is part of TALER
--- Copyright (C) 2014--2020 Taler Systems SA
---
--- TALER is free software; you can redistribute it and/or modify it under the
--- terms of the GNU General Public License as published by the Free Software
--- Foundation; either version 3, or (at your option) any later version.
---
--- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
--- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
--- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
---
--- You should have received a copy of the GNU General Public License along with
--- TALER; see the file COPYING. If not, see
---
-
--- Everything in one big transaction
-BEGIN;
-
--- Check patch versioning is in place.
-SELECT _v.register_patch('auditor-0001', NULL, NULL);
-
-
-CREATE TABLE IF NOT EXISTS auditor_exchanges
- (master_pub BYTEA PRIMARY KEY CHECK (LENGTH(master_pub)=32)
- ,exchange_url VARCHAR NOT NULL
- );
--- Table with list of signing keys of exchanges we are auditing
-CREATE TABLE IF NOT EXISTS auditor_exchange_signkeys
- (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
- ,ep_start INT8 NOT NULL
- ,ep_expire INT8 NOT NULL
- ,ep_end INT8 NOT NULL
- ,exchange_pub BYTEA NOT NULL CHECK (LENGTH(exchange_pub)=32)
- ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)
- );
--- Table with all of the denomination keys that the auditor
--- is aware of.
-CREATE TABLE IF NOT EXISTS auditor_denominations
- (denom_pub_hash BYTEA PRIMARY KEY CHECK (LENGTH(denom_pub_hash)=64)
- ,master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
- ,valid_from INT8 NOT NULL
- ,expire_withdraw INT8 NOT NULL
- ,expire_deposit INT8 NOT NULL
- ,expire_legal INT8 NOT NULL
- ,coin_val INT8 NOT NULL
- ,coin_frac INT4 NOT NULL
- ,fee_withdraw_val INT8 NOT NULL
- ,fee_withdraw_frac INT4 NOT NULL
- ,fee_deposit_val INT8 NOT NULL
- ,fee_deposit_frac INT4 NOT NULL
- ,fee_refresh_val INT8 NOT NULL
- ,fee_refresh_frac INT4 NOT NULL
- ,fee_refund_val INT8 NOT NULL
- ,fee_refund_frac INT4 NOT NULL
- );
--- Table indicating up to which transactions the auditor has
--- processed the exchange database. Used for SELECTing the
--- statements to process. The indices below include the last
--- serial ID from the respective tables that we have
--- processed. Thus, we need to select those table entries that are
--- strictly larger (and process in monotonically increasing
--- order).
-CREATE TABLE IF NOT EXISTS auditor_progress_reserve
- (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
- ,last_reserve_in_serial_id INT8 NOT NULL DEFAULT 0
- ,last_reserve_out_serial_id INT8 NOT NULL DEFAULT 0
- ,last_reserve_recoup_serial_id INT8 NOT NULL DEFAULT 0
- ,last_reserve_close_serial_id INT8 NOT NULL DEFAULT 0
- );
-CREATE TABLE IF NOT EXISTS auditor_progress_aggregation
- (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
- ,last_wire_out_serial_id INT8 NOT NULL DEFAULT 0
- );
-CREATE TABLE IF NOT EXISTS auditor_progress_deposit_confirmation
- (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
- ,last_deposit_confirmation_serial_id INT8 NOT NULL DEFAULT 0
- );
-CREATE TABLE IF NOT EXISTS auditor_progress_coin
- (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
- ,last_withdraw_serial_id INT8 NOT NULL DEFAULT 0
- ,last_deposit_serial_id INT8 NOT NULL DEFAULT 0
- ,last_melt_serial_id INT8 NOT NULL DEFAULT 0
- ,last_refund_serial_id INT8 NOT NULL DEFAULT 0
- ,last_recoup_serial_id INT8 NOT NULL DEFAULT 0
- ,last_recoup_refresh_serial_id INT8 NOT NULL DEFAULT 0
- );
-CREATE TABLE IF NOT EXISTS wire_auditor_account_progress
- (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
- ,account_name TEXT NOT NULL
- ,last_wire_reserve_in_serial_id INT8 NOT NULL DEFAULT 0
- ,last_wire_wire_out_serial_id INT8 NOT NULL DEFAULT 0
- ,wire_in_off INT8
- ,wire_out_off INT8
- );
-CREATE TABLE IF NOT EXISTS wire_auditor_progress
- (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
- ,last_timestamp INT8 NOT NULL
- ,last_reserve_close_uuid INT8 NOT NULL
- );
--- Table with all of the customer reserves and their respective
--- balances that the auditor is aware of.
--- last_reserve_out_serial_id marks the last withdrawal from
--- reserves_out about this reserve that the auditor is aware of,
--- and last_reserve_in_serial_id is the last reserve_in
--- operation about this reserve that the auditor is aware of.
-CREATE TABLE IF NOT EXISTS auditor_reserves
- (reserve_pub BYTEA NOT NULL CHECK(LENGTH(reserve_pub)=32)
- ,master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
- ,reserve_balance_val INT8 NOT NULL
- ,reserve_balance_frac INT4 NOT NULL
- ,withdraw_fee_balance_val INT8 NOT NULL
- ,withdraw_fee_balance_frac INT4 NOT NULL
- ,expiration_date INT8 NOT NULL
- ,auditor_reserves_rowid BIGSERIAL UNIQUE
- ,origin_account TEXT
- );
-CREATE INDEX IF NOT EXISTS auditor_reserves_by_reserve_pub
- ON auditor_reserves
- (reserve_pub);
--- Table with the sum of the balances of all customer reserves
--- (by exchange's master public key)
-CREATE TABLE IF NOT EXISTS auditor_reserve_balance
- (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
- ,reserve_balance_val INT8 NOT NULL
- ,reserve_balance_frac INT4 NOT NULL
- ,withdraw_fee_balance_val INT8 NOT NULL
- ,withdraw_fee_balance_frac INT4 NOT NULL
- );
--- Table with the sum of the balances of all wire fees
--- (by exchange's master public key)
-CREATE TABLE IF NOT EXISTS auditor_wire_fee_balance
- (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
- ,wire_fee_balance_val INT8 NOT NULL
- ,wire_fee_balance_frac INT4 NOT NULL
- );
--- Table with all of the outstanding denomination coins that the
--- exchange is aware of and what the respective balances are
--- (outstanding as well as issued overall which implies the
--- maximum value at risk). We also count the number of coins
--- issued (withdraw, refresh-reveal) and the number of coins seen
--- at the exchange (refresh-commit, deposit), not just the amounts. */GNUNET_PQ_make_execute (
-CREATE TABLE IF NOT EXISTS auditor_denomination_pending
- (denom_pub_hash BYTEA PRIMARY KEY REFERENCES auditor_denominations (denom_pub_hash) ON DELETE CASCADE
- ,denom_balance_val INT8 NOT NULL
- ,denom_balance_frac INT4 NOT NULL
- ,denom_loss_val INT8 NOT NULL
- ,denom_loss_frac INT4 NOT NULL
- ,num_issued INT8 NOT NULL
- ,denom_risk_val INT8 NOT NULL
- ,denom_risk_frac INT4 NOT NULL
- ,recoup_loss_val INT8 NOT NULL
- ,recoup_loss_frac INT4 NOT NULL
- );
--- Table with the sum of the outstanding coins from
--- auditor_denomination_pending (denom_pubs must belong to the
--- respective's exchange's master public key); it represents the
--- auditor_balance_summary of the exchange at this point (modulo
--- unexpected historic_loss-style events where denomination keys are
--- compromised)
-CREATE TABLE IF NOT EXISTS auditor_balance_summary
- (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
- ,denom_balance_val INT8 NOT NULL
- ,denom_balance_frac INT4 NOT NULL
- ,deposit_fee_balance_val INT8 NOT NULL
- ,deposit_fee_balance_frac INT4 NOT NULL
- ,melt_fee_balance_val INT8 NOT NULL
- ,melt_fee_balance_frac INT4 NOT NULL
- ,refund_fee_balance_val INT8 NOT NULL
- ,refund_fee_balance_frac INT4 NOT NULL
- ,risk_val INT8 NOT NULL
- ,risk_frac INT4 NOT NULL
- ,loss_val INT8 NOT NULL
- ,loss_frac INT4 NOT NULL
- ,irregular_recoup_val INT8 NOT NULL
- ,irregular_recoup_frac INT4 NOT NULL
- );
--- Table with historic profits; basically, when a denom_pub has
--- expired and everything associated with it is garbage collected,
--- the final profits end up in here; note that the denom_pub here
--- is not a foreign key, we just keep it as a reference point.
--- revenue_balance is the sum of all of the profits we made on the
--- coin except for withdraw fees (which are in
--- historic_reserve_revenue); the deposit, melt and refund fees are given
--- individually; the delta to the revenue_balance is from coins that
--- were withdrawn but never deposited prior to expiration.
-CREATE TABLE IF NOT EXISTS auditor_historic_denomination_revenue
- (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
- ,denom_pub_hash BYTEA PRIMARY KEY CHECK (LENGTH(denom_pub_hash)=64)
- ,revenue_timestamp INT8 NOT NULL
- ,revenue_balance_val INT8 NOT NULL
- ,revenue_balance_frac INT4 NOT NULL
- ,loss_balance_val INT8 NOT NULL
- ,loss_balance_frac INT4 NOT NULL
- );
--- Table with historic profits from reserves; we eventually
--- GC auditor_historic_reserve_revenue, and then store the totals
--- in here (by time intervals).
-CREATE TABLE IF NOT EXISTS auditor_historic_reserve_summary
- (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
- ,start_date INT8 NOT NULL
- ,end_date INT8 NOT NULL
- ,reserve_profits_val INT8 NOT NULL
- ,reserve_profits_frac INT4 NOT NULL
- );
-CREATE INDEX IF NOT EXISTS auditor_historic_reserve_summary_by_master_pub_start_date
- ON auditor_historic_reserve_summary
- (master_pub
- ,start_date);
--- Table with deposit confirmation sent to us by merchants;
--- we must check that the exchange reported these properly.
-CREATE TABLE IF NOT EXISTS deposit_confirmations
- (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
- ,serial_id BIGSERIAL UNIQUE
- ,h_contract_terms BYTEA CHECK (LENGTH(h_contract_terms)=64)
- ,h_wire BYTEA CHECK (LENGTH(h_wire)=64)
- ,timestamp INT8 NOT NULL
- ,refund_deadline INT8 NOT NULL
- ,amount_without_fee_val INT8 NOT NULL
- ,amount_without_fee_frac INT4 NOT NULL
- ,coin_pub BYTEA CHECK (LENGTH(coin_pub)=32)
- ,merchant_pub BYTEA CHECK (LENGTH(merchant_pub)=32)
- ,exchange_sig BYTEA CHECK (LENGTH(exchange_sig)=64)
- ,exchange_pub BYTEA CHECK (LENGTH(exchange_pub)=32)
- ,master_sig BYTEA CHECK (LENGTH(master_sig)=64)
- ,PRIMARY KEY (h_contract_terms,h_wire,coin_pub,merchant_pub,exchange_sig,exchange_pub,master_sig)
- );
--- Table with the sum of the ledger, auditor_historic_revenue and
--- the auditor_reserve_balance. This is the
--- final amount that the exchange should have in its bank account
--- right now.
-CREATE TABLE IF NOT EXISTS auditor_predicted_result
- (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
- ,balance_val INT8 NOT NULL
- ,balance_frac INT4 NOT NULL
- );
-
--- Finally, commit everything
-COMMIT;
diff --git a/src/auditordb/Makefile.am b/src/auditordb/Makefile.am
index 1378c549..3efdc200 100644
--- a/src/auditordb/Makefile.am
+++ b/src/auditordb/Makefile.am
@@ -14,8 +14,8 @@ pkgcfg_DATA = \
sqldir = $(prefix)/share/taler/sql/auditor/
sql_DATA = \
- 0000.sql \
- 0001.sql \
+ auditor-0000.sql \
+ auditor-0001.sql \
drop0000.sql \
restart0000.sql
diff --git a/src/auditordb/auditor-0000.sql b/src/auditordb/auditor-0000.sql
new file mode 100644
index 00000000..1483e201
--- /dev/null
+++ b/src/auditordb/auditor-0000.sql
@@ -0,0 +1,293 @@
+-- LICENSE AND COPYRIGHT
+--
+-- Copyright (C) 2010 Hubert depesz Lubaczewski
+--
+-- This program is distributed under the (Revised) BSD License:
+-- L
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+--
+-- * Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- * Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- * Neither the name of Hubert depesz Lubaczewski's Organization
+-- nor the names of its contributors may be used to endorse or
+-- promote products derived from this software without specific
+-- prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+-- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+-- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+-- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--
+-- Code origin: https://gitlab.com/depesz/Versioning/blob/master/install.versioning.sql
+--
+--
+-- # NAME
+--
+-- **Versioning** - simplistic take on tracking and applying changes to databases.
+--
+-- # DESCRIPTION
+--
+-- This project strives to provide simple way to manage changes to
+-- database.
+--
+-- Instead of making changes on development server, then finding
+-- differences between production and development, deciding which ones
+-- should be installed on production, and finding a way to install them -
+-- you start with writing diffs themselves!
+--
+-- # INSTALLATION
+--
+-- To install versioning simply run install.versioning.sql in your database
+-- (all of them: production, stage, test, devel, ...).
+--
+-- # USAGE
+--
+-- In your files with patches to database, put whole logic in single
+-- transaction, and use \_v.\* functions - usually \_v.register_patch() at
+-- least to make sure everything is OK.
+--
+-- For example. Let's assume you have patch files:
+--
+-- ## 0001.sql:
+--
+-- ```
+-- create table users (id serial primary key, username text);
+-- ```
+--
+-- ## 0002.sql:
+--
+-- ```
+-- insert into users (username) values ('depesz');
+-- ```
+-- To change it to use versioning you would change the files, to this
+-- state:
+--
+-- 0000.sql:
+--
+-- ```
+-- BEGIN;
+-- select _v.register_patch('000-base', NULL, NULL);
+-- create table users (id serial primary key, username text);
+-- COMMIT;
+-- ```
+--
+-- ## 0002.sql:
+--
+-- ```
+-- BEGIN;
+-- select _v.register_patch('001-users', ARRAY['000-base'], NULL);
+-- insert into users (username) values ('depesz');
+-- COMMIT;
+-- ```
+--
+-- This will make sure that patch 001-users can only be applied after
+-- 000-base.
+--
+-- # AVAILABLE FUNCTIONS
+--
+-- ## \_v.register_patch( TEXT )
+--
+-- Registers named patch, or dies if it is already registered.
+--
+-- Returns integer which is id of patch in \_v.patches table - only if it
+-- succeeded.
+--
+-- ## \_v.register_patch( TEXT, TEXT[] )
+--
+-- Same as \_v.register_patch( TEXT ), but checks is all given patches (given as
+-- array in second argument) are already registered.
+--
+-- ## \_v.register_patch( TEXT, TEXT[], TEXT[] )
+--
+-- Same as \_v.register_patch( TEXT, TEXT[] ), but also checks if there are no conflicts with preexisting patches.
+--
+-- Third argument is array of names of patches that conflict with current one. So
+-- if any of them is installed - register_patch will error out.
+--
+-- ## \_v.unregister_patch( TEXT )
+--
+-- Removes information about given patch from the versioning data.
+--
+-- It doesn't remove objects that were created by this patch - just removes
+-- metainformation.
+--
+-- ## \_v.assert_user_is_superuser()
+--
+-- Make sure that current patch is being loaded by superuser.
+--
+-- If it's not - it will raise exception, and break transaction.
+--
+-- ## \_v.assert_user_is_not_superuser()
+--
+-- Make sure that current patch is not being loaded by superuser.
+--
+-- If it is - it will raise exception, and break transaction.
+--
+-- ## \_v.assert_user_is_one_of(TEXT, TEXT, ... )
+--
+-- Make sure that current patch is being loaded by one of listed users.
+--
+-- If ```current_user``` is not listed as one of arguments - function will raise
+-- exception and break the transaction.
+
+BEGIN;
+
+-- This file adds versioning support to database it will be loaded to.
+-- It requires that PL/pgSQL is already loaded - will raise exception otherwise.
+-- All versioning "stuff" (tables, functions) is in "_v" schema.
+
+-- All functions are defined as 'RETURNS SETOF INT4' to be able to make them to RETURN literaly nothing (0 rows).
+-- >> RETURNS VOID<< IS similar, but it still outputs "empty line" in psql when calling.
+CREATE SCHEMA IF NOT EXISTS _v;
+COMMENT ON SCHEMA _v IS 'Schema for versioning data and functionality.';
+
+CREATE TABLE IF NOT EXISTS _v.patches (
+ patch_name TEXT PRIMARY KEY,
+ applied_tsz TIMESTAMPTZ NOT NULL DEFAULT now(),
+ applied_by TEXT NOT NULL,
+ requires TEXT[],
+ conflicts TEXT[]
+);
+COMMENT ON TABLE _v.patches IS 'Contains information about what patches are currently applied on database.';
+COMMENT ON COLUMN _v.patches.patch_name IS 'Name of patch, has to be unique for every patch.';
+COMMENT ON COLUMN _v.patches.applied_tsz IS 'When the patch was applied.';
+COMMENT ON COLUMN _v.patches.applied_by IS 'Who applied this patch (PostgreSQL username)';
+COMMENT ON COLUMN _v.patches.requires IS 'List of patches that are required for given patch.';
+COMMENT ON COLUMN _v.patches.conflicts IS 'List of patches that conflict with given patch.';
+
+CREATE OR REPLACE FUNCTION _v.register_patch( IN in_patch_name TEXT, IN in_requirements TEXT[], in_conflicts TEXT[], OUT versioning INT4 ) RETURNS setof INT4 AS $$
+DECLARE
+ t_text TEXT;
+ t_text_a TEXT[];
+ i INT4;
+BEGIN
+ -- Thanks to this we know only one patch will be applied at a time
+ LOCK TABLE _v.patches IN EXCLUSIVE MODE;
+
+ SELECT patch_name INTO t_text FROM _v.patches WHERE patch_name = in_patch_name;
+ IF FOUND THEN
+ RAISE EXCEPTION 'Patch % is already applied!', in_patch_name;
+ END IF;
+
+ t_text_a := ARRAY( SELECT patch_name FROM _v.patches WHERE patch_name = any( in_conflicts ) );
+ IF array_upper( t_text_a, 1 ) IS NOT NULL THEN
+ RAISE EXCEPTION 'Versioning patches conflict. Conflicting patche(s) installed: %.', array_to_string( t_text_a, ', ' );
+ END IF;
+
+ IF array_upper( in_requirements, 1 ) IS NOT NULL THEN
+ t_text_a := '{}';
+ FOR i IN array_lower( in_requirements, 1 ) .. array_upper( in_requirements, 1 ) LOOP
+ SELECT patch_name INTO t_text FROM _v.patches WHERE patch_name = in_requirements[i];
+ IF NOT FOUND THEN
+ t_text_a := t_text_a || in_requirements[i];
+ END IF;
+ END LOOP;
+ IF array_upper( t_text_a, 1 ) IS NOT NULL THEN
+ RAISE EXCEPTION 'Missing prerequisite(s): %.', array_to_string( t_text_a, ', ' );
+ END IF;
+ END IF;
+
+ INSERT INTO _v.patches (patch_name, applied_tsz, applied_by, requires, conflicts ) VALUES ( in_patch_name, now(), current_user, coalesce( in_requirements, '{}' ), coalesce( in_conflicts, '{}' ) );
+ RETURN;
+END;
+$$ language plpgsql;
+COMMENT ON FUNCTION _v.register_patch( TEXT, TEXT[], TEXT[] ) IS 'Function to register patches in database. Raises exception if there are conflicts, prerequisites are not installed or the migration has already been installed.';
+
+CREATE OR REPLACE FUNCTION _v.register_patch( TEXT, TEXT[] ) RETURNS setof INT4 AS $$
+ SELECT _v.register_patch( $1, $2, NULL );
+$$ language sql;
+COMMENT ON FUNCTION _v.register_patch( TEXT, TEXT[] ) IS 'Wrapper to allow registration of patches without conflicts.';
+CREATE OR REPLACE FUNCTION _v.register_patch( TEXT ) RETURNS setof INT4 AS $$
+ SELECT _v.register_patch( $1, NULL, NULL );
+$$ language sql;
+COMMENT ON FUNCTION _v.register_patch( TEXT ) IS 'Wrapper to allow registration of patches without requirements and conflicts.';
+
+CREATE OR REPLACE FUNCTION _v.unregister_patch( IN in_patch_name TEXT, OUT versioning INT4 ) RETURNS setof INT4 AS $$
+DECLARE
+ i INT4;
+ t_text_a TEXT[];
+BEGIN
+ -- Thanks to this we know only one patch will be applied at a time
+ LOCK TABLE _v.patches IN EXCLUSIVE MODE;
+
+ t_text_a := ARRAY( SELECT patch_name FROM _v.patches WHERE in_patch_name = ANY( requires ) );
+ IF array_upper( t_text_a, 1 ) IS NOT NULL THEN
+ RAISE EXCEPTION 'Cannot uninstall %, as it is required by: %.', in_patch_name, array_to_string( t_text_a, ', ' );
+ END IF;
+
+ DELETE FROM _v.patches WHERE patch_name = in_patch_name;
+ GET DIAGNOSTICS i = ROW_COUNT;
+ IF i < 1 THEN
+ RAISE EXCEPTION 'Patch % is not installed, so it can''t be uninstalled!', in_patch_name;
+ END IF;
+
+ RETURN;
+END;
+$$ language plpgsql;
+COMMENT ON FUNCTION _v.unregister_patch( TEXT ) IS 'Function to unregister patches in database. Dies if the patch is not registered, or if unregistering it would break dependencies.';
+
+CREATE OR REPLACE FUNCTION _v.assert_patch_is_applied( IN in_patch_name TEXT ) RETURNS TEXT as $$
+DECLARE
+ t_text TEXT;
+BEGIN
+ SELECT patch_name INTO t_text FROM _v.patches WHERE patch_name = in_patch_name;
+ IF NOT FOUND THEN
+ RAISE EXCEPTION 'Patch % is not applied!', in_patch_name;
+ END IF;
+ RETURN format('Patch %s is applied.', in_patch_name);
+END;
+$$ language plpgsql;
+COMMENT ON FUNCTION _v.assert_patch_is_applied( TEXT ) IS 'Function that can be used to make sure that patch has been applied.';
+
+CREATE OR REPLACE FUNCTION _v.assert_user_is_superuser() RETURNS TEXT as $$
+DECLARE
+ v_super bool;
+BEGIN
+ SELECT usesuper INTO v_super FROM pg_user WHERE usename = current_user;
+ IF v_super THEN
+ RETURN 'assert_user_is_superuser: OK';
+ END IF;
+ RAISE EXCEPTION 'Current user is not superuser - cannot continue.';
+END;
+$$ language plpgsql;
+COMMENT ON FUNCTION _v.assert_user_is_superuser() IS 'Function that can be used to make sure that patch is being applied using superuser account.';
+
+CREATE OR REPLACE FUNCTION _v.assert_user_is_not_superuser() RETURNS TEXT as $$
+DECLARE
+ v_super bool;
+BEGIN
+ SELECT usesuper INTO v_super FROM pg_user WHERE usename = current_user;
+ IF v_super THEN
+ RAISE EXCEPTION 'Current user is superuser - cannot continue.';
+ END IF;
+ RETURN 'assert_user_is_not_superuser: OK';
+END;
+$$ language plpgsql;
+COMMENT ON FUNCTION _v.assert_user_is_not_superuser() IS 'Function that can be used to make sure that patch is being applied using normal (not superuser) account.';
+
+CREATE OR REPLACE FUNCTION _v.assert_user_is_one_of(VARIADIC p_acceptable_users TEXT[] ) RETURNS TEXT as $$
+DECLARE
+BEGIN
+ IF current_user = any( p_acceptable_users ) THEN
+ RETURN 'assert_user_is_one_of: OK';
+ END IF;
+ RAISE EXCEPTION 'User is not one of: % - cannot continue.', p_acceptable_users;
+END;
+$$ language plpgsql;
+COMMENT ON FUNCTION _v.assert_user_is_one_of(TEXT[]) IS 'Function that can be used to make sure that patch is being applied by one of defined users.';
+
+COMMIT;
diff --git a/src/auditordb/auditor-0001.sql b/src/auditordb/auditor-0001.sql
new file mode 100644
index 00000000..3e666519
--- /dev/null
+++ b/src/auditordb/auditor-0001.sql
@@ -0,0 +1,239 @@
+--
+-- This file is part of TALER
+-- Copyright (C) 2014--2020 Taler Systems SA
+--
+-- TALER is free software; you can redistribute it and/or modify it under the
+-- terms of the GNU General Public License as published by the Free Software
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see
+--
+
+-- Everything in one big transaction
+BEGIN;
+
+-- Check patch versioning is in place.
+SELECT _v.register_patch('auditor-0001', NULL, NULL);
+
+
+CREATE TABLE IF NOT EXISTS auditor_exchanges
+ (master_pub BYTEA PRIMARY KEY CHECK (LENGTH(master_pub)=32)
+ ,exchange_url VARCHAR NOT NULL
+ );
+-- Table with list of signing keys of exchanges we are auditing
+CREATE TABLE IF NOT EXISTS auditor_exchange_signkeys
+ (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
+ ,ep_start INT8 NOT NULL
+ ,ep_expire INT8 NOT NULL
+ ,ep_end INT8 NOT NULL
+ ,exchange_pub BYTEA NOT NULL CHECK (LENGTH(exchange_pub)=32)
+ ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)
+ );
+-- Table with all of the denomination keys that the auditor
+-- is aware of.
+CREATE TABLE IF NOT EXISTS auditor_denominations
+ (denom_pub_hash BYTEA PRIMARY KEY CHECK (LENGTH(denom_pub_hash)=64)
+ ,master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
+ ,valid_from INT8 NOT NULL
+ ,expire_withdraw INT8 NOT NULL
+ ,expire_deposit INT8 NOT NULL
+ ,expire_legal INT8 NOT NULL
+ ,coin_val INT8 NOT NULL
+ ,coin_frac INT4 NOT NULL
+ ,fee_withdraw_val INT8 NOT NULL
+ ,fee_withdraw_frac INT4 NOT NULL
+ ,fee_deposit_val INT8 NOT NULL
+ ,fee_deposit_frac INT4 NOT NULL
+ ,fee_refresh_val INT8 NOT NULL
+ ,fee_refresh_frac INT4 NOT NULL
+ ,fee_refund_val INT8 NOT NULL
+ ,fee_refund_frac INT4 NOT NULL
+ );
+-- Table indicating up to which transactions the auditor has
+-- processed the exchange database. Used for SELECTing the
+-- statements to process. The indices below include the last
+-- serial ID from the respective tables that we have
+-- processed. Thus, we need to select those table entries that are
+-- strictly larger (and process in monotonically increasing
+-- order).
+CREATE TABLE IF NOT EXISTS auditor_progress_reserve
+ (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
+ ,last_reserve_in_serial_id INT8 NOT NULL DEFAULT 0
+ ,last_reserve_out_serial_id INT8 NOT NULL DEFAULT 0
+ ,last_reserve_recoup_serial_id INT8 NOT NULL DEFAULT 0
+ ,last_reserve_close_serial_id INT8 NOT NULL DEFAULT 0
+ );
+CREATE TABLE IF NOT EXISTS auditor_progress_aggregation
+ (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
+ ,last_wire_out_serial_id INT8 NOT NULL DEFAULT 0
+ );
+CREATE TABLE IF NOT EXISTS auditor_progress_deposit_confirmation
+ (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
+ ,last_deposit_confirmation_serial_id INT8 NOT NULL DEFAULT 0
+ );
+CREATE TABLE IF NOT EXISTS auditor_progress_coin
+ (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
+ ,last_withdraw_serial_id INT8 NOT NULL DEFAULT 0
+ ,last_deposit_serial_id INT8 NOT NULL DEFAULT 0
+ ,last_melt_serial_id INT8 NOT NULL DEFAULT 0
+ ,last_refund_serial_id INT8 NOT NULL DEFAULT 0
+ ,last_recoup_serial_id INT8 NOT NULL DEFAULT 0
+ ,last_recoup_refresh_serial_id INT8 NOT NULL DEFAULT 0
+ );
+CREATE TABLE IF NOT EXISTS wire_auditor_account_progress
+ (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
+ ,account_name TEXT NOT NULL
+ ,last_wire_reserve_in_serial_id INT8 NOT NULL DEFAULT 0
+ ,last_wire_wire_out_serial_id INT8 NOT NULL DEFAULT 0
+ ,wire_in_off INT8
+ ,wire_out_off INT8
+ );
+CREATE TABLE IF NOT EXISTS wire_auditor_progress
+ (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
+ ,last_timestamp INT8 NOT NULL
+ ,last_reserve_close_uuid INT8 NOT NULL
+ );
+-- Table with all of the customer reserves and their respective
+-- balances that the auditor is aware of.
+-- last_reserve_out_serial_id marks the last withdrawal from
+-- reserves_out about this reserve that the auditor is aware of,
+-- and last_reserve_in_serial_id is the last reserve_in
+-- operation about this reserve that the auditor is aware of.
+CREATE TABLE IF NOT EXISTS auditor_reserves
+ (reserve_pub BYTEA NOT NULL CHECK(LENGTH(reserve_pub)=32)
+ ,master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
+ ,reserve_balance_val INT8 NOT NULL
+ ,reserve_balance_frac INT4 NOT NULL
+ ,withdraw_fee_balance_val INT8 NOT NULL
+ ,withdraw_fee_balance_frac INT4 NOT NULL
+ ,expiration_date INT8 NOT NULL
+ ,auditor_reserves_rowid BIGSERIAL UNIQUE
+ ,origin_account TEXT
+ );
+CREATE INDEX IF NOT EXISTS auditor_reserves_by_reserve_pub
+ ON auditor_reserves
+ (reserve_pub);
+-- Table with the sum of the balances of all customer reserves
+-- (by exchange's master public key)
+CREATE TABLE IF NOT EXISTS auditor_reserve_balance
+ (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
+ ,reserve_balance_val INT8 NOT NULL
+ ,reserve_balance_frac INT4 NOT NULL
+ ,withdraw_fee_balance_val INT8 NOT NULL
+ ,withdraw_fee_balance_frac INT4 NOT NULL
+ );
+-- Table with the sum of the balances of all wire fees
+-- (by exchange's master public key)
+CREATE TABLE IF NOT EXISTS auditor_wire_fee_balance
+ (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
+ ,wire_fee_balance_val INT8 NOT NULL
+ ,wire_fee_balance_frac INT4 NOT NULL
+ );
+-- Table with all of the outstanding denomination coins that the
+-- exchange is aware of and what the respective balances are
+-- (outstanding as well as issued overall which implies the
+-- maximum value at risk). We also count the number of coins
+-- issued (withdraw, refresh-reveal) and the number of coins seen
+-- at the exchange (refresh-commit, deposit), not just the amounts. */GNUNET_PQ_make_execute (
+CREATE TABLE IF NOT EXISTS auditor_denomination_pending
+ (denom_pub_hash BYTEA PRIMARY KEY REFERENCES auditor_denominations (denom_pub_hash) ON DELETE CASCADE
+ ,denom_balance_val INT8 NOT NULL
+ ,denom_balance_frac INT4 NOT NULL
+ ,denom_loss_val INT8 NOT NULL
+ ,denom_loss_frac INT4 NOT NULL
+ ,num_issued INT8 NOT NULL
+ ,denom_risk_val INT8 NOT NULL
+ ,denom_risk_frac INT4 NOT NULL
+ ,recoup_loss_val INT8 NOT NULL
+ ,recoup_loss_frac INT4 NOT NULL
+ );
+-- Table with the sum of the outstanding coins from
+-- auditor_denomination_pending (denom_pubs must belong to the
+-- respective's exchange's master public key); it represents the
+-- auditor_balance_summary of the exchange at this point (modulo
+-- unexpected historic_loss-style events where denomination keys are
+-- compromised)
+CREATE TABLE IF NOT EXISTS auditor_balance_summary
+ (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
+ ,denom_balance_val INT8 NOT NULL
+ ,denom_balance_frac INT4 NOT NULL
+ ,deposit_fee_balance_val INT8 NOT NULL
+ ,deposit_fee_balance_frac INT4 NOT NULL
+ ,melt_fee_balance_val INT8 NOT NULL
+ ,melt_fee_balance_frac INT4 NOT NULL
+ ,refund_fee_balance_val INT8 NOT NULL
+ ,refund_fee_balance_frac INT4 NOT NULL
+ ,risk_val INT8 NOT NULL
+ ,risk_frac INT4 NOT NULL
+ ,loss_val INT8 NOT NULL
+ ,loss_frac INT4 NOT NULL
+ ,irregular_recoup_val INT8 NOT NULL
+ ,irregular_recoup_frac INT4 NOT NULL
+ );
+-- Table with historic profits; basically, when a denom_pub has
+-- expired and everything associated with it is garbage collected,
+-- the final profits end up in here; note that the denom_pub here
+-- is not a foreign key, we just keep it as a reference point.
+-- revenue_balance is the sum of all of the profits we made on the
+-- coin except for withdraw fees (which are in
+-- historic_reserve_revenue); the deposit, melt and refund fees are given
+-- individually; the delta to the revenue_balance is from coins that
+-- were withdrawn but never deposited prior to expiration.
+CREATE TABLE IF NOT EXISTS auditor_historic_denomination_revenue
+ (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
+ ,denom_pub_hash BYTEA PRIMARY KEY CHECK (LENGTH(denom_pub_hash)=64)
+ ,revenue_timestamp INT8 NOT NULL
+ ,revenue_balance_val INT8 NOT NULL
+ ,revenue_balance_frac INT4 NOT NULL
+ ,loss_balance_val INT8 NOT NULL
+ ,loss_balance_frac INT4 NOT NULL
+ );
+-- Table with historic profits from reserves; we eventually
+-- GC auditor_historic_reserve_revenue, and then store the totals
+-- in here (by time intervals).
+CREATE TABLE IF NOT EXISTS auditor_historic_reserve_summary
+ (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
+ ,start_date INT8 NOT NULL
+ ,end_date INT8 NOT NULL
+ ,reserve_profits_val INT8 NOT NULL
+ ,reserve_profits_frac INT4 NOT NULL
+ );
+CREATE INDEX IF NOT EXISTS auditor_historic_reserve_summary_by_master_pub_start_date
+ ON auditor_historic_reserve_summary
+ (master_pub
+ ,start_date);
+-- Table with deposit confirmation sent to us by merchants;
+-- we must check that the exchange reported these properly.
+CREATE TABLE IF NOT EXISTS deposit_confirmations
+ (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
+ ,serial_id BIGSERIAL UNIQUE
+ ,h_contract_terms BYTEA CHECK (LENGTH(h_contract_terms)=64)
+ ,h_wire BYTEA CHECK (LENGTH(h_wire)=64)
+ ,timestamp INT8 NOT NULL
+ ,refund_deadline INT8 NOT NULL
+ ,amount_without_fee_val INT8 NOT NULL
+ ,amount_without_fee_frac INT4 NOT NULL
+ ,coin_pub BYTEA CHECK (LENGTH(coin_pub)=32)
+ ,merchant_pub BYTEA CHECK (LENGTH(merchant_pub)=32)
+ ,exchange_sig BYTEA CHECK (LENGTH(exchange_sig)=64)
+ ,exchange_pub BYTEA CHECK (LENGTH(exchange_pub)=32)
+ ,master_sig BYTEA CHECK (LENGTH(master_sig)=64)
+ ,PRIMARY KEY (h_contract_terms,h_wire,coin_pub,merchant_pub,exchange_sig,exchange_pub,master_sig)
+ );
+-- Table with the sum of the ledger, auditor_historic_revenue and
+-- the auditor_reserve_balance. This is the
+-- final amount that the exchange should have in its bank account
+-- right now.
+CREATE TABLE IF NOT EXISTS auditor_predicted_result
+ (master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE
+ ,balance_val INT8 NOT NULL
+ ,balance_frac INT4 NOT NULL
+ );
+
+-- Finally, commit everything
+COMMIT;
diff --git a/src/auditordb/plugin_auditordb_postgres.c b/src/auditordb/plugin_auditordb_postgres.c
index 08d24fd7..ca07d406 100644
--- a/src/auditordb/plugin_auditordb_postgres.c
+++ b/src/auditordb/plugin_auditordb_postgres.c
@@ -80,15 +80,9 @@ struct PostgresClosure
pthread_key_t db_conn_threadlocal;
/**
- * Directory with SQL statements to run to create tables.
+ * Our configuration.
*/
- char *sql_dir;
-
- /**
- * Database connection string, as read from
- * the configuration.
- */
- char *connection_cfg_str;
+ const struct GNUNET_CONFIGURATION_Handle *cfg;
/**
* Which currency should we assume all amounts to be in?
@@ -114,16 +108,12 @@ postgres_drop_tables (void *cls,
{
struct PostgresClosure *pc = cls;
struct GNUNET_PQ_Context *conn;
- char *exec_dir;
-
- GNUNET_asprintf (&exec_dir,
- (drop_exchangelist) ? "%sdrop" : "%srestart",
- pc->sql_dir);
- conn = GNUNET_PQ_connect (pc->connection_cfg_str,
- exec_dir,
- NULL,
- NULL);
- GNUNET_free (exec_dir);
+
+ conn = GNUNET_PQ_connect_with_cfg (pc->cfg,
+ "auditordb-postgres",
+ (drop_exchangelist) ? "drop" : "restart",
+ NULL,
+ NULL);
if (NULL == conn)
return GNUNET_SYSERR;
GNUNET_PQ_disconnect (conn);
@@ -143,10 +133,11 @@ postgres_create_tables (void *cls)
struct PostgresClosure *pc = cls;
struct GNUNET_PQ_Context *conn;
- conn = GNUNET_PQ_connect (pc->connection_cfg_str,
- pc->sql_dir,
- NULL,
- NULL);
+ conn = GNUNET_PQ_connect_with_cfg (pc->cfg,
+ "auditordb-postgres",
+ "auditor-",
+ NULL,
+ NULL);
if (NULL == conn)
return GNUNET_SYSERR;
GNUNET_PQ_disconnect (conn);
@@ -734,10 +725,11 @@ postgres_get_session (void *cls)
GNUNET_PQ_reconnect_if_down (session->conn);
return session;
}
- db_conn = GNUNET_PQ_connect (pc->connection_cfg_str,
- NULL,
- NULL,
- ps);
+ db_conn = GNUNET_PQ_connect_with_cfg (pc->cfg,
+ "auditordb-postgres",
+ NULL,
+ NULL,
+ ps);
if (NULL == db_conn)
return NULL;
session = GNUNET_new (struct TALER_AUDITORDB_Session);
@@ -897,10 +889,11 @@ postgres_gc (void *cls)
};
now = GNUNET_TIME_absolute_get ();
- conn = GNUNET_PQ_connect (pc->connection_cfg_str,
- NULL,
- NULL,
- ps);
+ conn = GNUNET_PQ_connect_with_cfg (pc->cfg,
+ "auditordb-postgres",
+ NULL,
+ NULL,
+ ps);
if (NULL == conn)
return GNUNET_SYSERR;
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -3247,50 +3240,16 @@ libtaler_plugin_auditordb_postgres_init (void *cls)
const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
struct PostgresClosure *pg;
struct TALER_AUDITORDB_Plugin *plugin;
- const char *ec;
pg = GNUNET_new (struct PostgresClosure);
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_filename (cfg,
- "auditordb-postgres",
- "SQL_DIR",
- &pg->sql_dir))
- {
- GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
- "auditordb-postgres",
- "SQL_DIR");
- GNUNET_free (pg);
- return NULL;
- }
+ pg->cfg = cfg;
if (0 != pthread_key_create (&pg->db_conn_threadlocal,
&db_conn_destroy))
{
TALER_LOG_ERROR ("Cannnot create pthread key.\n");
- GNUNET_free (pg->sql_dir);
GNUNET_free (pg);
return NULL;
}
- ec = getenv ("TALER_AUDITORDB_POSTGRES_CONFIG");
- if (NULL != ec)
- {
- pg->connection_cfg_str = GNUNET_strdup (ec);
- }
- else
- {
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (cfg,
- "auditordb-postgres",
- "CONFIG",
- &pg->connection_cfg_str))
- {
- GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
- "auditordb-postgres",
- "CONFIG");
- GNUNET_free (pg->sql_dir);
- GNUNET_free (pg);
- return NULL;
- }
- }
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
"taler",
@@ -3300,8 +3259,6 @@ libtaler_plugin_auditordb_postgres_init (void *cls)
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"taler",
"CURRENCY");
- GNUNET_free (pg->connection_cfg_str);
- GNUNET_free (pg->sql_dir);
GNUNET_free (pg);
return NULL;
}
@@ -3407,8 +3364,6 @@ libtaler_plugin_auditordb_postgres_done (void *cls)
struct TALER_AUDITORDB_Plugin *plugin = cls;
struct PostgresClosure *pg = plugin->cls;
- GNUNET_free (pg->connection_cfg_str);
- GNUNET_free (pg->sql_dir);
GNUNET_free (pg->currency);
GNUNET_free (pg);
GNUNET_free (plugin);
diff --git a/src/exchangedb/0000.sql b/src/exchangedb/0000.sql
deleted file mode 100644
index 1483e201..00000000
--- a/src/exchangedb/0000.sql
+++ /dev/null
@@ -1,293 +0,0 @@
--- LICENSE AND COPYRIGHT
---
--- Copyright (C) 2010 Hubert depesz Lubaczewski
---
--- This program is distributed under the (Revised) BSD License:
--- L
---
--- Redistribution and use in source and binary forms, with or without
--- modification, are permitted provided that the following conditions
--- are met:
---
--- * Redistributions of source code must retain the above copyright
--- notice, this list of conditions and the following disclaimer.
---
--- * Redistributions in binary form must reproduce the above copyright
--- notice, this list of conditions and the following disclaimer in the
--- documentation and/or other materials provided with the distribution.
---
--- * Neither the name of Hubert depesz Lubaczewski's Organization
--- nor the names of its contributors may be used to endorse or
--- promote products derived from this software without specific
--- prior written permission.
---
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
--- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
--- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
--- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
--- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
--- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
--- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
--- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
--- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---
--- Code origin: https://gitlab.com/depesz/Versioning/blob/master/install.versioning.sql
---
---
--- # NAME
---
--- **Versioning** - simplistic take on tracking and applying changes to databases.
---
--- # DESCRIPTION
---
--- This project strives to provide simple way to manage changes to
--- database.
---
--- Instead of making changes on development server, then finding
--- differences between production and development, deciding which ones
--- should be installed on production, and finding a way to install them -
--- you start with writing diffs themselves!
---
--- # INSTALLATION
---
--- To install versioning simply run install.versioning.sql in your database
--- (all of them: production, stage, test, devel, ...).
---
--- # USAGE
---
--- In your files with patches to database, put whole logic in single
--- transaction, and use \_v.\* functions - usually \_v.register_patch() at
--- least to make sure everything is OK.
---
--- For example. Let's assume you have patch files:
---
--- ## 0001.sql:
---
--- ```
--- create table users (id serial primary key, username text);
--- ```
---
--- ## 0002.sql:
---
--- ```
--- insert into users (username) values ('depesz');
--- ```
--- To change it to use versioning you would change the files, to this
--- state:
---
--- 0000.sql:
---
--- ```
--- BEGIN;
--- select _v.register_patch('000-base', NULL, NULL);
--- create table users (id serial primary key, username text);
--- COMMIT;
--- ```
---
--- ## 0002.sql:
---
--- ```
--- BEGIN;
--- select _v.register_patch('001-users', ARRAY['000-base'], NULL);
--- insert into users (username) values ('depesz');
--- COMMIT;
--- ```
---
--- This will make sure that patch 001-users can only be applied after
--- 000-base.
---
--- # AVAILABLE FUNCTIONS
---
--- ## \_v.register_patch( TEXT )
---
--- Registers named patch, or dies if it is already registered.
---
--- Returns integer which is id of patch in \_v.patches table - only if it
--- succeeded.
---
--- ## \_v.register_patch( TEXT, TEXT[] )
---
--- Same as \_v.register_patch( TEXT ), but checks is all given patches (given as
--- array in second argument) are already registered.
---
--- ## \_v.register_patch( TEXT, TEXT[], TEXT[] )
---
--- Same as \_v.register_patch( TEXT, TEXT[] ), but also checks if there are no conflicts with preexisting patches.
---
--- Third argument is array of names of patches that conflict with current one. So
--- if any of them is installed - register_patch will error out.
---
--- ## \_v.unregister_patch( TEXT )
---
--- Removes information about given patch from the versioning data.
---
--- It doesn't remove objects that were created by this patch - just removes
--- metainformation.
---
--- ## \_v.assert_user_is_superuser()
---
--- Make sure that current patch is being loaded by superuser.
---
--- If it's not - it will raise exception, and break transaction.
---
--- ## \_v.assert_user_is_not_superuser()
---
--- Make sure that current patch is not being loaded by superuser.
---
--- If it is - it will raise exception, and break transaction.
---
--- ## \_v.assert_user_is_one_of(TEXT, TEXT, ... )
---
--- Make sure that current patch is being loaded by one of listed users.
---
--- If ```current_user``` is not listed as one of arguments - function will raise
--- exception and break the transaction.
-
-BEGIN;
-
--- This file adds versioning support to database it will be loaded to.
--- It requires that PL/pgSQL is already loaded - will raise exception otherwise.
--- All versioning "stuff" (tables, functions) is in "_v" schema.
-
--- All functions are defined as 'RETURNS SETOF INT4' to be able to make them to RETURN literaly nothing (0 rows).
--- >> RETURNS VOID<< IS similar, but it still outputs "empty line" in psql when calling.
-CREATE SCHEMA IF NOT EXISTS _v;
-COMMENT ON SCHEMA _v IS 'Schema for versioning data and functionality.';
-
-CREATE TABLE IF NOT EXISTS _v.patches (
- patch_name TEXT PRIMARY KEY,
- applied_tsz TIMESTAMPTZ NOT NULL DEFAULT now(),
- applied_by TEXT NOT NULL,
- requires TEXT[],
- conflicts TEXT[]
-);
-COMMENT ON TABLE _v.patches IS 'Contains information about what patches are currently applied on database.';
-COMMENT ON COLUMN _v.patches.patch_name IS 'Name of patch, has to be unique for every patch.';
-COMMENT ON COLUMN _v.patches.applied_tsz IS 'When the patch was applied.';
-COMMENT ON COLUMN _v.patches.applied_by IS 'Who applied this patch (PostgreSQL username)';
-COMMENT ON COLUMN _v.patches.requires IS 'List of patches that are required for given patch.';
-COMMENT ON COLUMN _v.patches.conflicts IS 'List of patches that conflict with given patch.';
-
-CREATE OR REPLACE FUNCTION _v.register_patch( IN in_patch_name TEXT, IN in_requirements TEXT[], in_conflicts TEXT[], OUT versioning INT4 ) RETURNS setof INT4 AS $$
-DECLARE
- t_text TEXT;
- t_text_a TEXT[];
- i INT4;
-BEGIN
- -- Thanks to this we know only one patch will be applied at a time
- LOCK TABLE _v.patches IN EXCLUSIVE MODE;
-
- SELECT patch_name INTO t_text FROM _v.patches WHERE patch_name = in_patch_name;
- IF FOUND THEN
- RAISE EXCEPTION 'Patch % is already applied!', in_patch_name;
- END IF;
-
- t_text_a := ARRAY( SELECT patch_name FROM _v.patches WHERE patch_name = any( in_conflicts ) );
- IF array_upper( t_text_a, 1 ) IS NOT NULL THEN
- RAISE EXCEPTION 'Versioning patches conflict. Conflicting patche(s) installed: %.', array_to_string( t_text_a, ', ' );
- END IF;
-
- IF array_upper( in_requirements, 1 ) IS NOT NULL THEN
- t_text_a := '{}';
- FOR i IN array_lower( in_requirements, 1 ) .. array_upper( in_requirements, 1 ) LOOP
- SELECT patch_name INTO t_text FROM _v.patches WHERE patch_name = in_requirements[i];
- IF NOT FOUND THEN
- t_text_a := t_text_a || in_requirements[i];
- END IF;
- END LOOP;
- IF array_upper( t_text_a, 1 ) IS NOT NULL THEN
- RAISE EXCEPTION 'Missing prerequisite(s): %.', array_to_string( t_text_a, ', ' );
- END IF;
- END IF;
-
- INSERT INTO _v.patches (patch_name, applied_tsz, applied_by, requires, conflicts ) VALUES ( in_patch_name, now(), current_user, coalesce( in_requirements, '{}' ), coalesce( in_conflicts, '{}' ) );
- RETURN;
-END;
-$$ language plpgsql;
-COMMENT ON FUNCTION _v.register_patch( TEXT, TEXT[], TEXT[] ) IS 'Function to register patches in database. Raises exception if there are conflicts, prerequisites are not installed or the migration has already been installed.';
-
-CREATE OR REPLACE FUNCTION _v.register_patch( TEXT, TEXT[] ) RETURNS setof INT4 AS $$
- SELECT _v.register_patch( $1, $2, NULL );
-$$ language sql;
-COMMENT ON FUNCTION _v.register_patch( TEXT, TEXT[] ) IS 'Wrapper to allow registration of patches without conflicts.';
-CREATE OR REPLACE FUNCTION _v.register_patch( TEXT ) RETURNS setof INT4 AS $$
- SELECT _v.register_patch( $1, NULL, NULL );
-$$ language sql;
-COMMENT ON FUNCTION _v.register_patch( TEXT ) IS 'Wrapper to allow registration of patches without requirements and conflicts.';
-
-CREATE OR REPLACE FUNCTION _v.unregister_patch( IN in_patch_name TEXT, OUT versioning INT4 ) RETURNS setof INT4 AS $$
-DECLARE
- i INT4;
- t_text_a TEXT[];
-BEGIN
- -- Thanks to this we know only one patch will be applied at a time
- LOCK TABLE _v.patches IN EXCLUSIVE MODE;
-
- t_text_a := ARRAY( SELECT patch_name FROM _v.patches WHERE in_patch_name = ANY( requires ) );
- IF array_upper( t_text_a, 1 ) IS NOT NULL THEN
- RAISE EXCEPTION 'Cannot uninstall %, as it is required by: %.', in_patch_name, array_to_string( t_text_a, ', ' );
- END IF;
-
- DELETE FROM _v.patches WHERE patch_name = in_patch_name;
- GET DIAGNOSTICS i = ROW_COUNT;
- IF i < 1 THEN
- RAISE EXCEPTION 'Patch % is not installed, so it can''t be uninstalled!', in_patch_name;
- END IF;
-
- RETURN;
-END;
-$$ language plpgsql;
-COMMENT ON FUNCTION _v.unregister_patch( TEXT ) IS 'Function to unregister patches in database. Dies if the patch is not registered, or if unregistering it would break dependencies.';
-
-CREATE OR REPLACE FUNCTION _v.assert_patch_is_applied( IN in_patch_name TEXT ) RETURNS TEXT as $$
-DECLARE
- t_text TEXT;
-BEGIN
- SELECT patch_name INTO t_text FROM _v.patches WHERE patch_name = in_patch_name;
- IF NOT FOUND THEN
- RAISE EXCEPTION 'Patch % is not applied!', in_patch_name;
- END IF;
- RETURN format('Patch %s is applied.', in_patch_name);
-END;
-$$ language plpgsql;
-COMMENT ON FUNCTION _v.assert_patch_is_applied( TEXT ) IS 'Function that can be used to make sure that patch has been applied.';
-
-CREATE OR REPLACE FUNCTION _v.assert_user_is_superuser() RETURNS TEXT as $$
-DECLARE
- v_super bool;
-BEGIN
- SELECT usesuper INTO v_super FROM pg_user WHERE usename = current_user;
- IF v_super THEN
- RETURN 'assert_user_is_superuser: OK';
- END IF;
- RAISE EXCEPTION 'Current user is not superuser - cannot continue.';
-END;
-$$ language plpgsql;
-COMMENT ON FUNCTION _v.assert_user_is_superuser() IS 'Function that can be used to make sure that patch is being applied using superuser account.';
-
-CREATE OR REPLACE FUNCTION _v.assert_user_is_not_superuser() RETURNS TEXT as $$
-DECLARE
- v_super bool;
-BEGIN
- SELECT usesuper INTO v_super FROM pg_user WHERE usename = current_user;
- IF v_super THEN
- RAISE EXCEPTION 'Current user is superuser - cannot continue.';
- END IF;
- RETURN 'assert_user_is_not_superuser: OK';
-END;
-$$ language plpgsql;
-COMMENT ON FUNCTION _v.assert_user_is_not_superuser() IS 'Function that can be used to make sure that patch is being applied using normal (not superuser) account.';
-
-CREATE OR REPLACE FUNCTION _v.assert_user_is_one_of(VARIADIC p_acceptable_users TEXT[] ) RETURNS TEXT as $$
-DECLARE
-BEGIN
- IF current_user = any( p_acceptable_users ) THEN
- RETURN 'assert_user_is_one_of: OK';
- END IF;
- RAISE EXCEPTION 'User is not one of: % - cannot continue.', p_acceptable_users;
-END;
-$$ language plpgsql;
-COMMENT ON FUNCTION _v.assert_user_is_one_of(TEXT[]) IS 'Function that can be used to make sure that patch is being applied by one of defined users.';
-
-COMMIT;
diff --git a/src/exchangedb/0001.sql b/src/exchangedb/0001.sql
deleted file mode 100644
index 02dc68cf..00000000
--- a/src/exchangedb/0001.sql
+++ /dev/null
@@ -1,368 +0,0 @@
---
--- This file is part of TALER
--- Copyright (C) 2014--2020 Taler Systems SA
---
--- TALER is free software; you can redistribute it and/or modify it under the
--- terms of the GNU General Public License as published by the Free Software
--- Foundation; either version 3, or (at your option) any later version.
---
--- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
--- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
--- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
---
--- You should have received a copy of the GNU General Public License along with
--- TALER; see the file COPYING. If not, see
---
-
--- Everything in one big transaction
-BEGIN;
-
--- Check patch versioning is in place.
-SELECT _v.register_patch('exchange-0001', NULL, NULL);
-
-
--- Main denominations table. All the coins the exchange knows about.
-CREATE TABLE IF NOT EXISTS denominations
- (denom_pub_hash BYTEA PRIMARY KEY CHECK (LENGTH(denom_pub_hash)=64)
- ,denom_pub BYTEA NOT NULL
- ,master_pub BYTEA NOT NULL CHECK (LENGTH(master_pub)=32)
- ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)
- ,valid_from INT8 NOT NULL
- ,expire_withdraw INT8 NOT NULL
- ,expire_deposit INT8 NOT NULL
- ,expire_legal INT8 NOT NULL
- ,coin_val INT8 NOT NULL
- ,coin_frac INT4 NOT NULL
- ,fee_withdraw_val INT8 NOT NULL
- ,fee_withdraw_frac INT4 NOT NULL
- ,fee_deposit_val INT8 NOT NULL
- ,fee_deposit_frac INT4 NOT NULL
- ,fee_refresh_val INT8 NOT NULL
- ,fee_refresh_frac INT4 NOT NULL
- ,fee_refund_val INT8 NOT NULL
- ,fee_refund_frac INT4 NOT NULL
- );
-CREATE INDEX IF NOT EXISTS denominations_expire_legal_index
- ON denominations
- (expire_legal);
-
--- denomination_revocations table is for remembering which denomination keys have been revoked
-CREATE TABLE IF NOT EXISTS denomination_revocations
- (denom_revocations_serial_id BIGSERIAL UNIQUE
- ,denom_pub_hash BYTEA PRIMARY KEY REFERENCES denominations (denom_pub_hash) ON DELETE CASCADE
- ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)
- );
--- reserves table is for summarization of a reserve. It is updated when new
--- funds are added and existing funds are withdrawn. The 'expiration_date'
--- can be used to eventually get rid of reserves that have not been used
--- for a very long time (usually by refunding the owner)
-CREATE TABLE IF NOT EXISTS reserves
- (reserve_pub BYTEA PRIMARY KEY CHECK(LENGTH(reserve_pub)=32)
- ,account_details TEXT NOT NULL
- ,current_balance_val INT8 NOT NULL
- ,current_balance_frac INT4 NOT NULL
- ,expiration_date INT8 NOT NULL
- ,gc_date INT8 NOT NULL
- );
--- index on reserves table (TODO: useless due to primary key!?)
-CREATE INDEX IF NOT EXISTS reserves_reserve_pub_index
- ON reserves
- (reserve_pub);
--- index for get_expired_reserves
-CREATE INDEX IF NOT EXISTS reserves_expiration_index
- ON reserves
- (expiration_date
- ,current_balance_val
- ,current_balance_frac
- );
--- index for reserve GC operations
-CREATE INDEX IF NOT EXISTS reserves_gc_index
- ON reserves
- (gc_date);
--- reserves_in table collects the transactions which transfer funds
--- into the reserve. The rows of this table correspond to each
--- incoming transaction.
-CREATE TABLE IF NOT EXISTS reserves_in
- (reserve_in_serial_id BIGSERIAL UNIQUE
- ,reserve_pub BYTEA NOT NULL REFERENCES reserves (reserve_pub) ON DELETE CASCADE
- ,wire_reference INT8 NOT NULL
- ,credit_val INT8 NOT NULL
- ,credit_frac INT4 NOT NULL
- ,sender_account_details TEXT NOT NULL
- ,exchange_account_section TEXT NOT NULL
- ,execution_date INT8 NOT NULL
- ,PRIMARY KEY (reserve_pub, wire_reference)
- );
--- Create indices on reserves_in
-CREATE INDEX IF NOT EXISTS reserves_in_execution_index
- ON reserves_in
- (exchange_account_section
- ,execution_date
- );
-CREATE INDEX IF NOT EXISTS reserves_in_exchange_account_serial
- ON reserves_in
- (exchange_account_section,
- reserve_in_serial_id DESC
- );
--- This table contains the data for wire transfers the exchange has
--- executed to close a reserve.
-CREATE TABLE IF NOT EXISTS reserves_close
- (close_uuid BIGSERIAL PRIMARY KEY
- ,reserve_pub BYTEA NOT NULL REFERENCES reserves (reserve_pub) ON DELETE CASCADE
- ,execution_date INT8 NOT NULL
- ,wtid BYTEA NOT NULL CHECK (LENGTH(wtid)=32)
- ,receiver_account TEXT NOT NULL
- ,amount_val INT8 NOT NULL
- ,amount_frac INT4 NOT NULL
- ,closing_fee_val INT8 NOT NULL
- ,closing_fee_frac INT4 NOT NULL);
-CREATE INDEX IF NOT EXISTS reserves_close_by_reserve
- ON reserves_close
- (reserve_pub);
--- Table with the withdraw operations that have been performed on a reserve.
--- The 'h_blind_ev' is the hash of the blinded coin. It serves as a primary
--- key, as (broken) clients that use a non-random coin and blinding factor
--- should fail to even withdraw, as otherwise the coins will fail to deposit
--- (as they really must be unique).
--- For the denom_pub, we do NOT CASCADE on DELETE, we may keep the denomination key alive!
-CREATE TABLE IF NOT EXISTS reserves_out
- (reserve_out_serial_id BIGSERIAL UNIQUE
- ,h_blind_ev BYTEA PRIMARY KEY CHECK (LENGTH(h_blind_ev)=64)
- ,denom_pub_hash BYTEA NOT NULL REFERENCES denominations (denom_pub_hash)
- ,denom_sig BYTEA NOT NULL
- ,reserve_pub BYTEA NOT NULL REFERENCES reserves (reserve_pub) ON DELETE CASCADE
- ,reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64)
- ,execution_date INT8 NOT NULL
- ,amount_with_fee_val INT8 NOT NULL
- ,amount_with_fee_frac INT4 NOT NULL
- );
--- Index blindcoins(reserve_pub) for get_reserves_out statement
-CREATE INDEX IF NOT EXISTS reserves_out_reserve_pub_index
- ON reserves_out
- (reserve_pub);
-CREATE INDEX IF NOT EXISTS reserves_out_execution_date
- ON reserves_out
- (execution_date);
-CREATE INDEX IF NOT EXISTS reserves_out_for_get_withdraw_info
- ON reserves_out
- (denom_pub_hash
- ,h_blind_ev
- );
--- Table with coins that have been (partially) spent, used to track
--- coin information only once.
-CREATE TABLE IF NOT EXISTS known_coins
- (coin_pub BYTEA NOT NULL PRIMARY KEY CHECK (LENGTH(coin_pub)=32)
- ,denom_pub_hash BYTEA NOT NULL REFERENCES denominations (denom_pub_hash) ON DELETE CASCADE
- ,denom_sig BYTEA NOT NULL
- );
-CREATE INDEX IF NOT EXISTS known_coins_by_denomination
- ON known_coins
- (denom_pub_hash);
--- Table with the commitments made when melting a coin. */
-CREATE TABLE IF NOT EXISTS refresh_commitments
- (melt_serial_id BIGSERIAL UNIQUE
- ,rc BYTEA PRIMARY KEY CHECK (LENGTH(rc)=64)
- ,old_coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub) ON DELETE CASCADE
- ,old_coin_sig BYTEA NOT NULL CHECK(LENGTH(old_coin_sig)=64)
- ,amount_with_fee_val INT8 NOT NULL
- ,amount_with_fee_frac INT4 NOT NULL
- ,noreveal_index INT4 NOT NULL
- );
-CREATE INDEX IF NOT EXISTS refresh_commitments_old_coin_pub_index
- ON refresh_commitments
- (old_coin_pub);
--- Table with the revelations about the new coins that are to be created
--- during a melting session. Includes the session, the cut-and-choose
--- index and the index of the new coin, and the envelope of the new
--- coin to be signed, as well as the encrypted information about the
--- private key and the blinding factor for the coin (for verification
--- in case this newcoin_index is chosen to be revealed)
-CREATE TABLE IF NOT EXISTS refresh_revealed_coins
- (rc BYTEA NOT NULL REFERENCES refresh_commitments (rc) ON DELETE CASCADE
- ,newcoin_index INT4 NOT NULL
- ,link_sig BYTEA NOT NULL CHECK(LENGTH(link_sig)=64)
- ,denom_pub_hash BYTEA NOT NULL REFERENCES denominations (denom_pub_hash) ON DELETE CASCADE
- ,coin_ev BYTEA UNIQUE NOT NULL
- ,h_coin_ev BYTEA NOT NULL CHECK(LENGTH(h_coin_ev)=64)
- ,ev_sig BYTEA NOT NULL
- ,PRIMARY KEY (rc, newcoin_index)
- ,UNIQUE (h_coin_ev)
- );
-CREATE INDEX IF NOT EXISTS refresh_revealed_coins_coin_pub_index
- ON refresh_revealed_coins
- (denom_pub_hash);
--- Table with the transfer keys of a refresh operation; includes
--- the rc for which this is the link information, the
--- transfer public key (for gamma) and the revealed transfer private
--- keys (array of TALER_CNC_KAPPA - 1 entries, with gamma being skipped) */
-CREATE TABLE IF NOT EXISTS refresh_transfer_keys
- (rc BYTEA NOT NULL PRIMARY KEY REFERENCES refresh_commitments (rc) ON DELETE CASCADE
- ,transfer_pub BYTEA NOT NULL CHECK(LENGTH(transfer_pub)=32)
- ,transfer_privs BYTEA NOT NULL
- );
--- for get_link (not sure if this helps, as there should be very few
--- transfer_pubs per rc, but at least in theory this helps the ORDER BY
--- clause.
-CREATE INDEX IF NOT EXISTS refresh_transfer_keys_coin_tpub
- ON refresh_transfer_keys
- (rc
- ,transfer_pub
- );
--- This table contains the wire transfers the exchange is supposed to
--- execute to transmit funds to the merchants (and manage refunds).
-CREATE TABLE IF NOT EXISTS deposits
- (deposit_serial_id BIGSERIAL PRIMARY KEY
- ,coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub) ON DELETE CASCADE
- ,amount_with_fee_val INT8 NOT NULL
- ,amount_with_fee_frac INT4 NOT NULL
- ,timestamp INT8 NOT NULL
- ,refund_deadline INT8 NOT NULL
- ,wire_deadline INT8 NOT NULL
- ,merchant_pub BYTEA NOT NULL CHECK (LENGTH(merchant_pub)=32)
- ,h_contract_terms BYTEA NOT NULL CHECK (LENGTH(h_contract_terms)=64)
- ,h_wire BYTEA NOT NULL CHECK (LENGTH(h_wire)=64)
- ,coin_sig BYTEA NOT NULL CHECK (LENGTH(coin_sig)=64)
- ,wire TEXT NOT NULL
- ,tiny BOOLEAN NOT NULL DEFAULT FALSE
- ,done BOOLEAN NOT NULL DEFAULT FALSE
- ,UNIQUE (coin_pub, merchant_pub, h_contract_terms)
- );
--- Index for get_deposit_for_wtid and get_deposit_statement */
-CREATE INDEX IF NOT EXISTS deposits_coin_pub_merchant_contract_index
- ON deposits
- (coin_pub
- ,merchant_pub
- ,h_contract_terms
- );
--- Index for deposits_get_ready
-CREATE INDEX IF NOT EXISTS deposits_get_ready_index
- ON deposits
- (tiny
- ,done
- ,wire_deadline
- ,refund_deadline
- );
--- Index for deposits_iterate_matching
-CREATE INDEX IF NOT EXISTS deposits_iterate_matching
- ON deposits
- (merchant_pub
- ,h_wire
- ,done
- ,wire_deadline
- );
--- Table with information about coins that have been refunded. (Technically
--- one of the deposit operations that a coin was involved with is refunded.)
--- The combo of coin_pub, merchant_pub, h_contract_terms and rtransaction_id
--- MUST be unique, and we usually select by coin_pub so that one goes first. */
-CREATE TABLE IF NOT EXISTS refunds
- (refund_serial_id BIGSERIAL UNIQUE
- ,coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub) ON DELETE CASCADE
- ,merchant_pub BYTEA NOT NULL CHECK(LENGTH(merchant_pub)=32)
- ,merchant_sig BYTEA NOT NULL CHECK(LENGTH(merchant_sig)=64)
- ,h_contract_terms BYTEA NOT NULL CHECK(LENGTH(h_contract_terms)=64)
- ,rtransaction_id INT8 NOT NULL
- ,amount_with_fee_val INT8 NOT NULL
- ,amount_with_fee_frac INT4 NOT NULL
- ,PRIMARY KEY (coin_pub, merchant_pub, h_contract_terms, rtransaction_id)
- );
-CREATE INDEX IF NOT EXISTS refunds_coin_pub_index
- ON refunds
- (coin_pub);
--- This table contains the data for
--- wire transfers the exchange has executed.
-CREATE TABLE IF NOT EXISTS wire_out
- (wireout_uuid BIGSERIAL PRIMARY KEY
- ,execution_date INT8 NOT NULL
- ,wtid_raw BYTEA UNIQUE NOT NULL CHECK (LENGTH(wtid_raw)=32)
- ,wire_target TEXT NOT NULL
- ,exchange_account_section TEXT NOT NULL
- ,amount_val INT8 NOT NULL
- ,amount_frac INT4 NOT NULL
- );
--- Table for the tracking API, mapping from wire transfer identifier
--- to transactions and back
-CREATE TABLE IF NOT EXISTS aggregation_tracking
- (aggregation_serial_id BIGSERIAL UNIQUE
- ,deposit_serial_id INT8 PRIMARY KEY REFERENCES deposits (deposit_serial_id) ON DELETE CASCADE
- ,wtid_raw BYTEA CONSTRAINT wire_out_ref REFERENCES wire_out(wtid_raw) ON DELETE CASCADE DEFERRABLE
- );
--- Index for lookup_transactions statement on wtid
-CREATE INDEX IF NOT EXISTS aggregation_tracking_wtid_index
- ON aggregation_tracking
- (wtid_raw);
--- Table for the wire fees.
-CREATE TABLE IF NOT EXISTS wire_fee
- (wire_method VARCHAR NOT NULL
- ,start_date INT8 NOT NULL
- ,end_date INT8 NOT NULL
- ,wire_fee_val INT8 NOT NULL
- ,wire_fee_frac INT4 NOT NULL
- ,closing_fee_val INT8 NOT NULL
- ,closing_fee_frac INT4 NOT NULL
- ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)
- ,PRIMARY KEY (wire_method, start_date)
- );
-CREATE INDEX IF NOT EXISTS wire_fee_gc_index
- ON wire_fee
- (end_date);
--- Table for /recoup information
--- Do not cascade on the coin_pub, as we may keep the coin alive! */
-CREATE TABLE IF NOT EXISTS recoup
- (recoup_uuid BIGSERIAL UNIQUE
- ,coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub)
- ,coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64)
- ,coin_blind BYTEA NOT NULL CHECK(LENGTH(coin_blind)=32)
- ,amount_val INT8 NOT NULL
- ,amount_frac INT4 NOT NULL
- ,timestamp INT8 NOT NULL
- ,h_blind_ev BYTEA NOT NULL REFERENCES reserves_out (h_blind_ev) ON DELETE CASCADE
- );
-CREATE INDEX IF NOT EXISTS recoup_by_coin_index
- ON recoup
- (coin_pub);
-CREATE INDEX IF NOT EXISTS recoup_by_h_blind_ev
- ON recoup
- (h_blind_ev);
-CREATE INDEX IF NOT EXISTS recoup_for_by_reserve
- ON recoup
- (coin_pub
- ,h_blind_ev
- );
--- Table for /recoup-refresh information
--- Do not cascade on the coin_pub, as we may keep the coin alive! */
-CREATE TABLE IF NOT EXISTS recoup_refresh
- (recoup_refresh_uuid BIGSERIAL UNIQUE
- ,coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub)
- ,coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64)
- ,coin_blind BYTEA NOT NULL CHECK(LENGTH(coin_blind)=32)
- ,amount_val INT8 NOT NULL
- ,amount_frac INT4 NOT NULL
- ,timestamp INT8 NOT NULL
- ,h_blind_ev BYTEA NOT NULL REFERENCES refresh_revealed_coins (h_coin_ev) ON DELETE CASCADE
- );
-CREATE INDEX IF NOT EXISTS recoup_refresh_by_coin_index
- ON recoup_refresh
- (coin_pub);
-CREATE INDEX IF NOT EXISTS recoup_refresh_by_h_blind_ev
- ON recoup_refresh
- (h_blind_ev);
-CREATE INDEX IF NOT EXISTS recoup_refresh_for_by_reserve
- ON recoup_refresh
- (coin_pub
- ,h_blind_ev
- );
--- This table contains the pre-commit data for
--- wire transfers the exchange is about to execute.
-CREATE TABLE IF NOT EXISTS prewire
- (prewire_uuid BIGSERIAL PRIMARY KEY
- ,type TEXT NOT NULL
- ,finished BOOLEAN NOT NULL DEFAULT false
- ,buf BYTEA NOT NULL
- );
--- Index for wire_prepare_data_get and gc_prewire statement
-CREATE INDEX IF NOT EXISTS prepare_iteration_index
- ON prewire
- (finished);
-
--- Complete transaction
-COMMIT;
diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am
index e7ac4d71..37809f6b 100644
--- a/src/exchangedb/Makefile.am
+++ b/src/exchangedb/Makefile.am
@@ -15,8 +15,8 @@ pkgcfg_DATA = \
sqldir = $(prefix)/share/taler/sql/exchange/
sql_DATA = \
- 0000.sql \
- 0001.sql \
+ exchange-0000.sql \
+ exchange-0001.sql \
drop0000.sql
EXTRA_DIST = \
diff --git a/src/exchangedb/exchange-0000.sql b/src/exchangedb/exchange-0000.sql
new file mode 100644
index 00000000..1483e201
--- /dev/null
+++ b/src/exchangedb/exchange-0000.sql
@@ -0,0 +1,293 @@
+-- LICENSE AND COPYRIGHT
+--
+-- Copyright (C) 2010 Hubert depesz Lubaczewski
+--
+-- This program is distributed under the (Revised) BSD License:
+-- L
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+--
+-- * Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- * Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- * Neither the name of Hubert depesz Lubaczewski's Organization
+-- nor the names of its contributors may be used to endorse or
+-- promote products derived from this software without specific
+-- prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+-- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+-- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+-- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--
+-- Code origin: https://gitlab.com/depesz/Versioning/blob/master/install.versioning.sql
+--
+--
+-- # NAME
+--
+-- **Versioning** - simplistic take on tracking and applying changes to databases.
+--
+-- # DESCRIPTION
+--
+-- This project strives to provide simple way to manage changes to
+-- database.
+--
+-- Instead of making changes on development server, then finding
+-- differences between production and development, deciding which ones
+-- should be installed on production, and finding a way to install them -
+-- you start with writing diffs themselves!
+--
+-- # INSTALLATION
+--
+-- To install versioning simply run install.versioning.sql in your database
+-- (all of them: production, stage, test, devel, ...).
+--
+-- # USAGE
+--
+-- In your files with patches to database, put whole logic in single
+-- transaction, and use \_v.\* functions - usually \_v.register_patch() at
+-- least to make sure everything is OK.
+--
+-- For example. Let's assume you have patch files:
+--
+-- ## 0001.sql:
+--
+-- ```
+-- create table users (id serial primary key, username text);
+-- ```
+--
+-- ## 0002.sql:
+--
+-- ```
+-- insert into users (username) values ('depesz');
+-- ```
+-- To change it to use versioning you would change the files, to this
+-- state:
+--
+-- 0000.sql:
+--
+-- ```
+-- BEGIN;
+-- select _v.register_patch('000-base', NULL, NULL);
+-- create table users (id serial primary key, username text);
+-- COMMIT;
+-- ```
+--
+-- ## 0002.sql:
+--
+-- ```
+-- BEGIN;
+-- select _v.register_patch('001-users', ARRAY['000-base'], NULL);
+-- insert into users (username) values ('depesz');
+-- COMMIT;
+-- ```
+--
+-- This will make sure that patch 001-users can only be applied after
+-- 000-base.
+--
+-- # AVAILABLE FUNCTIONS
+--
+-- ## \_v.register_patch( TEXT )
+--
+-- Registers named patch, or dies if it is already registered.
+--
+-- Returns integer which is id of patch in \_v.patches table - only if it
+-- succeeded.
+--
+-- ## \_v.register_patch( TEXT, TEXT[] )
+--
+-- Same as \_v.register_patch( TEXT ), but checks is all given patches (given as
+-- array in second argument) are already registered.
+--
+-- ## \_v.register_patch( TEXT, TEXT[], TEXT[] )
+--
+-- Same as \_v.register_patch( TEXT, TEXT[] ), but also checks if there are no conflicts with preexisting patches.
+--
+-- Third argument is array of names of patches that conflict with current one. So
+-- if any of them is installed - register_patch will error out.
+--
+-- ## \_v.unregister_patch( TEXT )
+--
+-- Removes information about given patch from the versioning data.
+--
+-- It doesn't remove objects that were created by this patch - just removes
+-- metainformation.
+--
+-- ## \_v.assert_user_is_superuser()
+--
+-- Make sure that current patch is being loaded by superuser.
+--
+-- If it's not - it will raise exception, and break transaction.
+--
+-- ## \_v.assert_user_is_not_superuser()
+--
+-- Make sure that current patch is not being loaded by superuser.
+--
+-- If it is - it will raise exception, and break transaction.
+--
+-- ## \_v.assert_user_is_one_of(TEXT, TEXT, ... )
+--
+-- Make sure that current patch is being loaded by one of listed users.
+--
+-- If ```current_user``` is not listed as one of arguments - function will raise
+-- exception and break the transaction.
+
+BEGIN;
+
+-- This file adds versioning support to database it will be loaded to.
+-- It requires that PL/pgSQL is already loaded - will raise exception otherwise.
+-- All versioning "stuff" (tables, functions) is in "_v" schema.
+
+-- All functions are defined as 'RETURNS SETOF INT4' to be able to make them to RETURN literaly nothing (0 rows).
+-- >> RETURNS VOID<< IS similar, but it still outputs "empty line" in psql when calling.
+CREATE SCHEMA IF NOT EXISTS _v;
+COMMENT ON SCHEMA _v IS 'Schema for versioning data and functionality.';
+
+CREATE TABLE IF NOT EXISTS _v.patches (
+ patch_name TEXT PRIMARY KEY,
+ applied_tsz TIMESTAMPTZ NOT NULL DEFAULT now(),
+ applied_by TEXT NOT NULL,
+ requires TEXT[],
+ conflicts TEXT[]
+);
+COMMENT ON TABLE _v.patches IS 'Contains information about what patches are currently applied on database.';
+COMMENT ON COLUMN _v.patches.patch_name IS 'Name of patch, has to be unique for every patch.';
+COMMENT ON COLUMN _v.patches.applied_tsz IS 'When the patch was applied.';
+COMMENT ON COLUMN _v.patches.applied_by IS 'Who applied this patch (PostgreSQL username)';
+COMMENT ON COLUMN _v.patches.requires IS 'List of patches that are required for given patch.';
+COMMENT ON COLUMN _v.patches.conflicts IS 'List of patches that conflict with given patch.';
+
+CREATE OR REPLACE FUNCTION _v.register_patch( IN in_patch_name TEXT, IN in_requirements TEXT[], in_conflicts TEXT[], OUT versioning INT4 ) RETURNS setof INT4 AS $$
+DECLARE
+ t_text TEXT;
+ t_text_a TEXT[];
+ i INT4;
+BEGIN
+ -- Thanks to this we know only one patch will be applied at a time
+ LOCK TABLE _v.patches IN EXCLUSIVE MODE;
+
+ SELECT patch_name INTO t_text FROM _v.patches WHERE patch_name = in_patch_name;
+ IF FOUND THEN
+ RAISE EXCEPTION 'Patch % is already applied!', in_patch_name;
+ END IF;
+
+ t_text_a := ARRAY( SELECT patch_name FROM _v.patches WHERE patch_name = any( in_conflicts ) );
+ IF array_upper( t_text_a, 1 ) IS NOT NULL THEN
+ RAISE EXCEPTION 'Versioning patches conflict. Conflicting patche(s) installed: %.', array_to_string( t_text_a, ', ' );
+ END IF;
+
+ IF array_upper( in_requirements, 1 ) IS NOT NULL THEN
+ t_text_a := '{}';
+ FOR i IN array_lower( in_requirements, 1 ) .. array_upper( in_requirements, 1 ) LOOP
+ SELECT patch_name INTO t_text FROM _v.patches WHERE patch_name = in_requirements[i];
+ IF NOT FOUND THEN
+ t_text_a := t_text_a || in_requirements[i];
+ END IF;
+ END LOOP;
+ IF array_upper( t_text_a, 1 ) IS NOT NULL THEN
+ RAISE EXCEPTION 'Missing prerequisite(s): %.', array_to_string( t_text_a, ', ' );
+ END IF;
+ END IF;
+
+ INSERT INTO _v.patches (patch_name, applied_tsz, applied_by, requires, conflicts ) VALUES ( in_patch_name, now(), current_user, coalesce( in_requirements, '{}' ), coalesce( in_conflicts, '{}' ) );
+ RETURN;
+END;
+$$ language plpgsql;
+COMMENT ON FUNCTION _v.register_patch( TEXT, TEXT[], TEXT[] ) IS 'Function to register patches in database. Raises exception if there are conflicts, prerequisites are not installed or the migration has already been installed.';
+
+CREATE OR REPLACE FUNCTION _v.register_patch( TEXT, TEXT[] ) RETURNS setof INT4 AS $$
+ SELECT _v.register_patch( $1, $2, NULL );
+$$ language sql;
+COMMENT ON FUNCTION _v.register_patch( TEXT, TEXT[] ) IS 'Wrapper to allow registration of patches without conflicts.';
+CREATE OR REPLACE FUNCTION _v.register_patch( TEXT ) RETURNS setof INT4 AS $$
+ SELECT _v.register_patch( $1, NULL, NULL );
+$$ language sql;
+COMMENT ON FUNCTION _v.register_patch( TEXT ) IS 'Wrapper to allow registration of patches without requirements and conflicts.';
+
+CREATE OR REPLACE FUNCTION _v.unregister_patch( IN in_patch_name TEXT, OUT versioning INT4 ) RETURNS setof INT4 AS $$
+DECLARE
+ i INT4;
+ t_text_a TEXT[];
+BEGIN
+ -- Thanks to this we know only one patch will be applied at a time
+ LOCK TABLE _v.patches IN EXCLUSIVE MODE;
+
+ t_text_a := ARRAY( SELECT patch_name FROM _v.patches WHERE in_patch_name = ANY( requires ) );
+ IF array_upper( t_text_a, 1 ) IS NOT NULL THEN
+ RAISE EXCEPTION 'Cannot uninstall %, as it is required by: %.', in_patch_name, array_to_string( t_text_a, ', ' );
+ END IF;
+
+ DELETE FROM _v.patches WHERE patch_name = in_patch_name;
+ GET DIAGNOSTICS i = ROW_COUNT;
+ IF i < 1 THEN
+ RAISE EXCEPTION 'Patch % is not installed, so it can''t be uninstalled!', in_patch_name;
+ END IF;
+
+ RETURN;
+END;
+$$ language plpgsql;
+COMMENT ON FUNCTION _v.unregister_patch( TEXT ) IS 'Function to unregister patches in database. Dies if the patch is not registered, or if unregistering it would break dependencies.';
+
+CREATE OR REPLACE FUNCTION _v.assert_patch_is_applied( IN in_patch_name TEXT ) RETURNS TEXT as $$
+DECLARE
+ t_text TEXT;
+BEGIN
+ SELECT patch_name INTO t_text FROM _v.patches WHERE patch_name = in_patch_name;
+ IF NOT FOUND THEN
+ RAISE EXCEPTION 'Patch % is not applied!', in_patch_name;
+ END IF;
+ RETURN format('Patch %s is applied.', in_patch_name);
+END;
+$$ language plpgsql;
+COMMENT ON FUNCTION _v.assert_patch_is_applied( TEXT ) IS 'Function that can be used to make sure that patch has been applied.';
+
+CREATE OR REPLACE FUNCTION _v.assert_user_is_superuser() RETURNS TEXT as $$
+DECLARE
+ v_super bool;
+BEGIN
+ SELECT usesuper INTO v_super FROM pg_user WHERE usename = current_user;
+ IF v_super THEN
+ RETURN 'assert_user_is_superuser: OK';
+ END IF;
+ RAISE EXCEPTION 'Current user is not superuser - cannot continue.';
+END;
+$$ language plpgsql;
+COMMENT ON FUNCTION _v.assert_user_is_superuser() IS 'Function that can be used to make sure that patch is being applied using superuser account.';
+
+CREATE OR REPLACE FUNCTION _v.assert_user_is_not_superuser() RETURNS TEXT as $$
+DECLARE
+ v_super bool;
+BEGIN
+ SELECT usesuper INTO v_super FROM pg_user WHERE usename = current_user;
+ IF v_super THEN
+ RAISE EXCEPTION 'Current user is superuser - cannot continue.';
+ END IF;
+ RETURN 'assert_user_is_not_superuser: OK';
+END;
+$$ language plpgsql;
+COMMENT ON FUNCTION _v.assert_user_is_not_superuser() IS 'Function that can be used to make sure that patch is being applied using normal (not superuser) account.';
+
+CREATE OR REPLACE FUNCTION _v.assert_user_is_one_of(VARIADIC p_acceptable_users TEXT[] ) RETURNS TEXT as $$
+DECLARE
+BEGIN
+ IF current_user = any( p_acceptable_users ) THEN
+ RETURN 'assert_user_is_one_of: OK';
+ END IF;
+ RAISE EXCEPTION 'User is not one of: % - cannot continue.', p_acceptable_users;
+END;
+$$ language plpgsql;
+COMMENT ON FUNCTION _v.assert_user_is_one_of(TEXT[]) IS 'Function that can be used to make sure that patch is being applied by one of defined users.';
+
+COMMIT;
diff --git a/src/exchangedb/exchange-0001.sql b/src/exchangedb/exchange-0001.sql
new file mode 100644
index 00000000..02dc68cf
--- /dev/null
+++ b/src/exchangedb/exchange-0001.sql
@@ -0,0 +1,368 @@
+--
+-- This file is part of TALER
+-- Copyright (C) 2014--2020 Taler Systems SA
+--
+-- TALER is free software; you can redistribute it and/or modify it under the
+-- terms of the GNU General Public License as published by the Free Software
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see
+--
+
+-- Everything in one big transaction
+BEGIN;
+
+-- Check patch versioning is in place.
+SELECT _v.register_patch('exchange-0001', NULL, NULL);
+
+
+-- Main denominations table. All the coins the exchange knows about.
+CREATE TABLE IF NOT EXISTS denominations
+ (denom_pub_hash BYTEA PRIMARY KEY CHECK (LENGTH(denom_pub_hash)=64)
+ ,denom_pub BYTEA NOT NULL
+ ,master_pub BYTEA NOT NULL CHECK (LENGTH(master_pub)=32)
+ ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)
+ ,valid_from INT8 NOT NULL
+ ,expire_withdraw INT8 NOT NULL
+ ,expire_deposit INT8 NOT NULL
+ ,expire_legal INT8 NOT NULL
+ ,coin_val INT8 NOT NULL
+ ,coin_frac INT4 NOT NULL
+ ,fee_withdraw_val INT8 NOT NULL
+ ,fee_withdraw_frac INT4 NOT NULL
+ ,fee_deposit_val INT8 NOT NULL
+ ,fee_deposit_frac INT4 NOT NULL
+ ,fee_refresh_val INT8 NOT NULL
+ ,fee_refresh_frac INT4 NOT NULL
+ ,fee_refund_val INT8 NOT NULL
+ ,fee_refund_frac INT4 NOT NULL
+ );
+CREATE INDEX IF NOT EXISTS denominations_expire_legal_index
+ ON denominations
+ (expire_legal);
+
+-- denomination_revocations table is for remembering which denomination keys have been revoked
+CREATE TABLE IF NOT EXISTS denomination_revocations
+ (denom_revocations_serial_id BIGSERIAL UNIQUE
+ ,denom_pub_hash BYTEA PRIMARY KEY REFERENCES denominations (denom_pub_hash) ON DELETE CASCADE
+ ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)
+ );
+-- reserves table is for summarization of a reserve. It is updated when new
+-- funds are added and existing funds are withdrawn. The 'expiration_date'
+-- can be used to eventually get rid of reserves that have not been used
+-- for a very long time (usually by refunding the owner)
+CREATE TABLE IF NOT EXISTS reserves
+ (reserve_pub BYTEA PRIMARY KEY CHECK(LENGTH(reserve_pub)=32)
+ ,account_details TEXT NOT NULL
+ ,current_balance_val INT8 NOT NULL
+ ,current_balance_frac INT4 NOT NULL
+ ,expiration_date INT8 NOT NULL
+ ,gc_date INT8 NOT NULL
+ );
+-- index on reserves table (TODO: useless due to primary key!?)
+CREATE INDEX IF NOT EXISTS reserves_reserve_pub_index
+ ON reserves
+ (reserve_pub);
+-- index for get_expired_reserves
+CREATE INDEX IF NOT EXISTS reserves_expiration_index
+ ON reserves
+ (expiration_date
+ ,current_balance_val
+ ,current_balance_frac
+ );
+-- index for reserve GC operations
+CREATE INDEX IF NOT EXISTS reserves_gc_index
+ ON reserves
+ (gc_date);
+-- reserves_in table collects the transactions which transfer funds
+-- into the reserve. The rows of this table correspond to each
+-- incoming transaction.
+CREATE TABLE IF NOT EXISTS reserves_in
+ (reserve_in_serial_id BIGSERIAL UNIQUE
+ ,reserve_pub BYTEA NOT NULL REFERENCES reserves (reserve_pub) ON DELETE CASCADE
+ ,wire_reference INT8 NOT NULL
+ ,credit_val INT8 NOT NULL
+ ,credit_frac INT4 NOT NULL
+ ,sender_account_details TEXT NOT NULL
+ ,exchange_account_section TEXT NOT NULL
+ ,execution_date INT8 NOT NULL
+ ,PRIMARY KEY (reserve_pub, wire_reference)
+ );
+-- Create indices on reserves_in
+CREATE INDEX IF NOT EXISTS reserves_in_execution_index
+ ON reserves_in
+ (exchange_account_section
+ ,execution_date
+ );
+CREATE INDEX IF NOT EXISTS reserves_in_exchange_account_serial
+ ON reserves_in
+ (exchange_account_section,
+ reserve_in_serial_id DESC
+ );
+-- This table contains the data for wire transfers the exchange has
+-- executed to close a reserve.
+CREATE TABLE IF NOT EXISTS reserves_close
+ (close_uuid BIGSERIAL PRIMARY KEY
+ ,reserve_pub BYTEA NOT NULL REFERENCES reserves (reserve_pub) ON DELETE CASCADE
+ ,execution_date INT8 NOT NULL
+ ,wtid BYTEA NOT NULL CHECK (LENGTH(wtid)=32)
+ ,receiver_account TEXT NOT NULL
+ ,amount_val INT8 NOT NULL
+ ,amount_frac INT4 NOT NULL
+ ,closing_fee_val INT8 NOT NULL
+ ,closing_fee_frac INT4 NOT NULL);
+CREATE INDEX IF NOT EXISTS reserves_close_by_reserve
+ ON reserves_close
+ (reserve_pub);
+-- Table with the withdraw operations that have been performed on a reserve.
+-- The 'h_blind_ev' is the hash of the blinded coin. It serves as a primary
+-- key, as (broken) clients that use a non-random coin and blinding factor
+-- should fail to even withdraw, as otherwise the coins will fail to deposit
+-- (as they really must be unique).
+-- For the denom_pub, we do NOT CASCADE on DELETE, we may keep the denomination key alive!
+CREATE TABLE IF NOT EXISTS reserves_out
+ (reserve_out_serial_id BIGSERIAL UNIQUE
+ ,h_blind_ev BYTEA PRIMARY KEY CHECK (LENGTH(h_blind_ev)=64)
+ ,denom_pub_hash BYTEA NOT NULL REFERENCES denominations (denom_pub_hash)
+ ,denom_sig BYTEA NOT NULL
+ ,reserve_pub BYTEA NOT NULL REFERENCES reserves (reserve_pub) ON DELETE CASCADE
+ ,reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64)
+ ,execution_date INT8 NOT NULL
+ ,amount_with_fee_val INT8 NOT NULL
+ ,amount_with_fee_frac INT4 NOT NULL
+ );
+-- Index blindcoins(reserve_pub) for get_reserves_out statement
+CREATE INDEX IF NOT EXISTS reserves_out_reserve_pub_index
+ ON reserves_out
+ (reserve_pub);
+CREATE INDEX IF NOT EXISTS reserves_out_execution_date
+ ON reserves_out
+ (execution_date);
+CREATE INDEX IF NOT EXISTS reserves_out_for_get_withdraw_info
+ ON reserves_out
+ (denom_pub_hash
+ ,h_blind_ev
+ );
+-- Table with coins that have been (partially) spent, used to track
+-- coin information only once.
+CREATE TABLE IF NOT EXISTS known_coins
+ (coin_pub BYTEA NOT NULL PRIMARY KEY CHECK (LENGTH(coin_pub)=32)
+ ,denom_pub_hash BYTEA NOT NULL REFERENCES denominations (denom_pub_hash) ON DELETE CASCADE
+ ,denom_sig BYTEA NOT NULL
+ );
+CREATE INDEX IF NOT EXISTS known_coins_by_denomination
+ ON known_coins
+ (denom_pub_hash);
+-- Table with the commitments made when melting a coin. */
+CREATE TABLE IF NOT EXISTS refresh_commitments
+ (melt_serial_id BIGSERIAL UNIQUE
+ ,rc BYTEA PRIMARY KEY CHECK (LENGTH(rc)=64)
+ ,old_coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub) ON DELETE CASCADE
+ ,old_coin_sig BYTEA NOT NULL CHECK(LENGTH(old_coin_sig)=64)
+ ,amount_with_fee_val INT8 NOT NULL
+ ,amount_with_fee_frac INT4 NOT NULL
+ ,noreveal_index INT4 NOT NULL
+ );
+CREATE INDEX IF NOT EXISTS refresh_commitments_old_coin_pub_index
+ ON refresh_commitments
+ (old_coin_pub);
+-- Table with the revelations about the new coins that are to be created
+-- during a melting session. Includes the session, the cut-and-choose
+-- index and the index of the new coin, and the envelope of the new
+-- coin to be signed, as well as the encrypted information about the
+-- private key and the blinding factor for the coin (for verification
+-- in case this newcoin_index is chosen to be revealed)
+CREATE TABLE IF NOT EXISTS refresh_revealed_coins
+ (rc BYTEA NOT NULL REFERENCES refresh_commitments (rc) ON DELETE CASCADE
+ ,newcoin_index INT4 NOT NULL
+ ,link_sig BYTEA NOT NULL CHECK(LENGTH(link_sig)=64)
+ ,denom_pub_hash BYTEA NOT NULL REFERENCES denominations (denom_pub_hash) ON DELETE CASCADE
+ ,coin_ev BYTEA UNIQUE NOT NULL
+ ,h_coin_ev BYTEA NOT NULL CHECK(LENGTH(h_coin_ev)=64)
+ ,ev_sig BYTEA NOT NULL
+ ,PRIMARY KEY (rc, newcoin_index)
+ ,UNIQUE (h_coin_ev)
+ );
+CREATE INDEX IF NOT EXISTS refresh_revealed_coins_coin_pub_index
+ ON refresh_revealed_coins
+ (denom_pub_hash);
+-- Table with the transfer keys of a refresh operation; includes
+-- the rc for which this is the link information, the
+-- transfer public key (for gamma) and the revealed transfer private
+-- keys (array of TALER_CNC_KAPPA - 1 entries, with gamma being skipped) */
+CREATE TABLE IF NOT EXISTS refresh_transfer_keys
+ (rc BYTEA NOT NULL PRIMARY KEY REFERENCES refresh_commitments (rc) ON DELETE CASCADE
+ ,transfer_pub BYTEA NOT NULL CHECK(LENGTH(transfer_pub)=32)
+ ,transfer_privs BYTEA NOT NULL
+ );
+-- for get_link (not sure if this helps, as there should be very few
+-- transfer_pubs per rc, but at least in theory this helps the ORDER BY
+-- clause.
+CREATE INDEX IF NOT EXISTS refresh_transfer_keys_coin_tpub
+ ON refresh_transfer_keys
+ (rc
+ ,transfer_pub
+ );
+-- This table contains the wire transfers the exchange is supposed to
+-- execute to transmit funds to the merchants (and manage refunds).
+CREATE TABLE IF NOT EXISTS deposits
+ (deposit_serial_id BIGSERIAL PRIMARY KEY
+ ,coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub) ON DELETE CASCADE
+ ,amount_with_fee_val INT8 NOT NULL
+ ,amount_with_fee_frac INT4 NOT NULL
+ ,timestamp INT8 NOT NULL
+ ,refund_deadline INT8 NOT NULL
+ ,wire_deadline INT8 NOT NULL
+ ,merchant_pub BYTEA NOT NULL CHECK (LENGTH(merchant_pub)=32)
+ ,h_contract_terms BYTEA NOT NULL CHECK (LENGTH(h_contract_terms)=64)
+ ,h_wire BYTEA NOT NULL CHECK (LENGTH(h_wire)=64)
+ ,coin_sig BYTEA NOT NULL CHECK (LENGTH(coin_sig)=64)
+ ,wire TEXT NOT NULL
+ ,tiny BOOLEAN NOT NULL DEFAULT FALSE
+ ,done BOOLEAN NOT NULL DEFAULT FALSE
+ ,UNIQUE (coin_pub, merchant_pub, h_contract_terms)
+ );
+-- Index for get_deposit_for_wtid and get_deposit_statement */
+CREATE INDEX IF NOT EXISTS deposits_coin_pub_merchant_contract_index
+ ON deposits
+ (coin_pub
+ ,merchant_pub
+ ,h_contract_terms
+ );
+-- Index for deposits_get_ready
+CREATE INDEX IF NOT EXISTS deposits_get_ready_index
+ ON deposits
+ (tiny
+ ,done
+ ,wire_deadline
+ ,refund_deadline
+ );
+-- Index for deposits_iterate_matching
+CREATE INDEX IF NOT EXISTS deposits_iterate_matching
+ ON deposits
+ (merchant_pub
+ ,h_wire
+ ,done
+ ,wire_deadline
+ );
+-- Table with information about coins that have been refunded. (Technically
+-- one of the deposit operations that a coin was involved with is refunded.)
+-- The combo of coin_pub, merchant_pub, h_contract_terms and rtransaction_id
+-- MUST be unique, and we usually select by coin_pub so that one goes first. */
+CREATE TABLE IF NOT EXISTS refunds
+ (refund_serial_id BIGSERIAL UNIQUE
+ ,coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub) ON DELETE CASCADE
+ ,merchant_pub BYTEA NOT NULL CHECK(LENGTH(merchant_pub)=32)
+ ,merchant_sig BYTEA NOT NULL CHECK(LENGTH(merchant_sig)=64)
+ ,h_contract_terms BYTEA NOT NULL CHECK(LENGTH(h_contract_terms)=64)
+ ,rtransaction_id INT8 NOT NULL
+ ,amount_with_fee_val INT8 NOT NULL
+ ,amount_with_fee_frac INT4 NOT NULL
+ ,PRIMARY KEY (coin_pub, merchant_pub, h_contract_terms, rtransaction_id)
+ );
+CREATE INDEX IF NOT EXISTS refunds_coin_pub_index
+ ON refunds
+ (coin_pub);
+-- This table contains the data for
+-- wire transfers the exchange has executed.
+CREATE TABLE IF NOT EXISTS wire_out
+ (wireout_uuid BIGSERIAL PRIMARY KEY
+ ,execution_date INT8 NOT NULL
+ ,wtid_raw BYTEA UNIQUE NOT NULL CHECK (LENGTH(wtid_raw)=32)
+ ,wire_target TEXT NOT NULL
+ ,exchange_account_section TEXT NOT NULL
+ ,amount_val INT8 NOT NULL
+ ,amount_frac INT4 NOT NULL
+ );
+-- Table for the tracking API, mapping from wire transfer identifier
+-- to transactions and back
+CREATE TABLE IF NOT EXISTS aggregation_tracking
+ (aggregation_serial_id BIGSERIAL UNIQUE
+ ,deposit_serial_id INT8 PRIMARY KEY REFERENCES deposits (deposit_serial_id) ON DELETE CASCADE
+ ,wtid_raw BYTEA CONSTRAINT wire_out_ref REFERENCES wire_out(wtid_raw) ON DELETE CASCADE DEFERRABLE
+ );
+-- Index for lookup_transactions statement on wtid
+CREATE INDEX IF NOT EXISTS aggregation_tracking_wtid_index
+ ON aggregation_tracking
+ (wtid_raw);
+-- Table for the wire fees.
+CREATE TABLE IF NOT EXISTS wire_fee
+ (wire_method VARCHAR NOT NULL
+ ,start_date INT8 NOT NULL
+ ,end_date INT8 NOT NULL
+ ,wire_fee_val INT8 NOT NULL
+ ,wire_fee_frac INT4 NOT NULL
+ ,closing_fee_val INT8 NOT NULL
+ ,closing_fee_frac INT4 NOT NULL
+ ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)
+ ,PRIMARY KEY (wire_method, start_date)
+ );
+CREATE INDEX IF NOT EXISTS wire_fee_gc_index
+ ON wire_fee
+ (end_date);
+-- Table for /recoup information
+-- Do not cascade on the coin_pub, as we may keep the coin alive! */
+CREATE TABLE IF NOT EXISTS recoup
+ (recoup_uuid BIGSERIAL UNIQUE
+ ,coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub)
+ ,coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64)
+ ,coin_blind BYTEA NOT NULL CHECK(LENGTH(coin_blind)=32)
+ ,amount_val INT8 NOT NULL
+ ,amount_frac INT4 NOT NULL
+ ,timestamp INT8 NOT NULL
+ ,h_blind_ev BYTEA NOT NULL REFERENCES reserves_out (h_blind_ev) ON DELETE CASCADE
+ );
+CREATE INDEX IF NOT EXISTS recoup_by_coin_index
+ ON recoup
+ (coin_pub);
+CREATE INDEX IF NOT EXISTS recoup_by_h_blind_ev
+ ON recoup
+ (h_blind_ev);
+CREATE INDEX IF NOT EXISTS recoup_for_by_reserve
+ ON recoup
+ (coin_pub
+ ,h_blind_ev
+ );
+-- Table for /recoup-refresh information
+-- Do not cascade on the coin_pub, as we may keep the coin alive! */
+CREATE TABLE IF NOT EXISTS recoup_refresh
+ (recoup_refresh_uuid BIGSERIAL UNIQUE
+ ,coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub)
+ ,coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64)
+ ,coin_blind BYTEA NOT NULL CHECK(LENGTH(coin_blind)=32)
+ ,amount_val INT8 NOT NULL
+ ,amount_frac INT4 NOT NULL
+ ,timestamp INT8 NOT NULL
+ ,h_blind_ev BYTEA NOT NULL REFERENCES refresh_revealed_coins (h_coin_ev) ON DELETE CASCADE
+ );
+CREATE INDEX IF NOT EXISTS recoup_refresh_by_coin_index
+ ON recoup_refresh
+ (coin_pub);
+CREATE INDEX IF NOT EXISTS recoup_refresh_by_h_blind_ev
+ ON recoup_refresh
+ (h_blind_ev);
+CREATE INDEX IF NOT EXISTS recoup_refresh_for_by_reserve
+ ON recoup_refresh
+ (coin_pub
+ ,h_blind_ev
+ );
+-- This table contains the pre-commit data for
+-- wire transfers the exchange is about to execute.
+CREATE TABLE IF NOT EXISTS prewire
+ (prewire_uuid BIGSERIAL PRIMARY KEY
+ ,type TEXT NOT NULL
+ ,finished BOOLEAN NOT NULL DEFAULT false
+ ,buf BYTEA NOT NULL
+ );
+-- Index for wire_prepare_data_get and gc_prewire statement
+CREATE INDEX IF NOT EXISTS prepare_iteration_index
+ ON prewire
+ (finished);
+
+-- Complete transaction
+COMMIT;
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index fe0021fa..9df2fe77 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -113,12 +113,6 @@ struct PostgresClosure
*/
const struct GNUNET_CONFIGURATION_Handle *cfg;
- /**
- * Database connection string, as read from
- * the configuration.
- */
- char *connection_cfg_str;
-
/**
* Directory with SQL statements to run to create tables.
*/
@@ -163,16 +157,12 @@ postgres_drop_tables (void *cls)
{
struct PostgresClosure *pc = cls;
struct GNUNET_PQ_Context *conn;
- char *drop_dir;
-
- GNUNET_asprintf (&drop_dir,
- "%sdrop",
- pc->sql_dir);
- conn = GNUNET_PQ_connect (pc->connection_cfg_str,
- drop_dir,
- NULL,
- NULL);
- GNUNET_free (drop_dir);
+
+ conn = GNUNET_PQ_connect_with_cfg (pc->cfg,
+ "exchangedb-postgres",
+ "drop",
+ NULL,
+ NULL);
if (NULL == conn)
return GNUNET_SYSERR;
GNUNET_PQ_disconnect (conn);
@@ -194,7 +184,7 @@ postgres_create_tables (void *cls)
conn = GNUNET_PQ_connect_with_cfg (pc->cfg,
"exchangedb-postgres",
- "",
+ "exchange-",
NULL,
NULL);
if (NULL == conn)
@@ -1393,10 +1383,11 @@ postgres_get_session (void *cls)
GNUNET_PQ_PREPARED_STATEMENT_END
};
- db_conn = GNUNET_PQ_connect (pc->connection_cfg_str,
- NULL,
- es,
- ps);
+ db_conn = GNUNET_PQ_connect_with_cfg (pc->cfg,
+ "exchangedb-postgres",
+ NULL,
+ es,
+ ps);
}
if (NULL == db_conn)
return NULL;
@@ -5377,10 +5368,11 @@ postgres_gc (void *cls)
GNUNET_PQ_PREPARED_STATEMENT_END
};
- conn = GNUNET_PQ_connect (pg->connection_cfg_str,
- NULL,
- NULL,
- ps);
+ conn = GNUNET_PQ_connect_with_cfg (pg->cfg,
+ "exchangedb-postgres",
+ NULL,
+ NULL,
+ ps);
}
if (NULL == conn)
return GNUNET_SYSERR;
@@ -7221,7 +7213,6 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
struct PostgresClosure *pg;
struct TALER_EXCHANGEDB_Plugin *plugin;
- const char *ec;
pg = GNUNET_new (struct PostgresClosure);
pg->cfg = cfg;
@@ -7246,28 +7237,6 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
GNUNET_free (pg);
return NULL;
}
- ec = getenv ("TALER_EXCHANGEDB_POSTGRES_CONFIG");
- if (NULL != ec)
- {
- pg->connection_cfg_str = GNUNET_strdup (ec);
- }
- else
- {
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (cfg,
- "exchangedb-postgres",
- "CONFIG",
- &pg->connection_cfg_str))
- {
- GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
- "exchangedb-postgres",
- "CONFIG");
- GNUNET_free (pg->sql_dir);
- GNUNET_free (pg);
- return NULL;
- }
- }
-
if ( (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_time (cfg,
"exchangedb",
@@ -7283,7 +7252,6 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"exchangedb",
"LEGAL/IDLE_RESERVE_EXPIRATION_TIME");
- GNUNET_free (pg->connection_cfg_str);
GNUNET_free (pg->sql_dir);
GNUNET_free (pg);
return NULL;
@@ -7297,7 +7265,6 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"taler",
"CURRENCY");
- GNUNET_free (pg->connection_cfg_str);
GNUNET_free (pg->sql_dir);
GNUNET_free (pg);
return NULL;
@@ -7413,7 +7380,6 @@ libtaler_plugin_exchangedb_postgres_done (void *cls)
/* If we launched a session for the main thread,
kill it here before we unload */
db_conn_destroy (pg->main_session);
- GNUNET_free (pg->connection_cfg_str);
GNUNET_free (pg->sql_dir);
GNUNET_free (pg->currency);
GNUNET_free (pg);
--
cgit v1.2.3