diff options
Diffstat (limited to 'src')
55 files changed, 601 insertions, 203 deletions
diff --git a/src/auditor/report-lib.c b/src/auditor/report-lib.c index 248e14e1f..bee7ec0f6 100644 --- a/src/auditor/report-lib.c +++ b/src/auditor/report-lib.c @@ -260,7 +260,7 @@ TALER_ARL_get_denomination_info ( * * @param analysis analysis to run * @param analysis_cls closure for @a analysis - * @return #GNUNET_OK if @a analysis succeessfully committed, + * @return #GNUNET_OK if @a analysis successfully committed, * #GNUNET_NO if we had an error on commit (retry may help) * #GNUNET_SYSERR on hard errors */ diff --git a/src/auditor/taler-helper-auditor-aggregation.c b/src/auditor/taler-helper-auditor-aggregation.c index fe95dfe3e..8b2808401 100644 --- a/src/auditor/taler-helper-auditor-aggregation.c +++ b/src/auditor/taler-helper-auditor-aggregation.c @@ -44,7 +44,7 @@ static struct TALER_AUDITORDB_ProgressPointAggregation ppa; static struct TALER_AUDITORDB_ProgressPointAggregation ppa_start; /** - * Array of reports about row inconsitencies. + * Array of reports about row inconsistencies. */ static json_t *report_row_inconsistencies; diff --git a/src/auditor/taler-helper-auditor-coins.c b/src/auditor/taler-helper-auditor-coins.c index 41c4f5205..23233dc7c 100644 --- a/src/auditor/taler-helper-auditor-coins.c +++ b/src/auditor/taler-helper-auditor-coins.c @@ -126,7 +126,7 @@ static json_t *report_bad_sig_losses; * Array of refresh transactions where the /refresh/reveal has not yet * happened (and may of course never happen). */ -static json_t *report_refreshs_hanging; +static json_t *report_refreshes_hanging; /** * Total amount lost by operations for which signatures were invalid. @@ -1340,7 +1340,7 @@ refresh_session_cb (void *cls, /* This can legitimately happen if reveal was not yet called or only with invalid data, even if the exchange is correctly operating. We still report it. */ - TALER_ARL_report (report_refreshs_hanging, + TALER_ARL_report (report_refreshes_hanging, GNUNET_JSON_PACK ( GNUNET_JSON_pack_uint64 ("row", rowid), @@ -2554,7 +2554,7 @@ analyze_coins (void *cls) if (0 > cc.qs) return cc.qs; - /* process refreshs */ + /* process refreshes */ if (0 > (qs = TALER_ARL_edb->select_refreshes_above_serial_id ( TALER_ARL_edb->cls, @@ -2739,7 +2739,7 @@ run (void *cls, GNUNET_assert (NULL != (report_bad_sig_losses = json_array ())); GNUNET_assert (NULL != - (report_refreshs_hanging = json_array ())); + (report_refreshes_hanging = json_array ())); if (GNUNET_OK != TALER_ARL_setup_sessions_and_run (&analyze_coins, NULL)) @@ -2792,7 +2792,7 @@ run (void *cls, report_bad_sig_losses), /* Tested in test-auditor.sh #12 */ GNUNET_JSON_pack_array_steal ("refresh_hanging", - report_refreshs_hanging), + report_refreshes_hanging), /* Tested in test-auditor.sh #18 */ GNUNET_JSON_pack_array_steal ("emergencies_by_count", report_emergencies_by_count), diff --git a/src/auditor/taler-helper-auditor-purses.c b/src/auditor/taler-helper-auditor-purses.c index f35020734..e728df0ee 100644 --- a/src/auditor/taler-helper-auditor-purses.c +++ b/src/auditor/taler-helper-auditor-purses.c @@ -54,12 +54,12 @@ static struct TALER_AUDITORDB_ProgressPointPurse ppp_start; static struct TALER_AUDITORDB_PurseBalance balance; /** - * Array of reports about row inconsitencies. + * Array of reports about row inconsistencies. */ static json_t *report_row_inconsistencies; /** - * Array of reports about purse balance insufficient inconsitencies. + * Array of reports about purse balance insufficient inconsistencies. */ static json_t *report_purse_balance_insufficient_inconsistencies; @@ -74,7 +74,7 @@ static struct TALER_Amount total_balance_insufficient_loss; static struct TALER_Amount total_delayed_decisions; /** - * Array of reports about purses's not being closed inconsitencies. + * Array of reports about purses's not being closed inconsistencies. */ static json_t *report_purse_not_closed_inconsistencies; diff --git a/src/auditor/taler-helper-auditor-reserves.c b/src/auditor/taler-helper-auditor-reserves.c index f589ebfda..6bd550373 100644 --- a/src/auditor/taler-helper-auditor-reserves.c +++ b/src/auditor/taler-helper-auditor-reserves.c @@ -54,7 +54,7 @@ static struct TALER_AUDITORDB_ProgressPointReserve ppr; static struct TALER_AUDITORDB_ProgressPointReserve ppr_start; /** - * Array of reports about row inconsitencies. + * Array of reports about row inconsistencies. */ static json_t *report_row_inconsistencies; @@ -65,12 +65,12 @@ static json_t *report_row_inconsistencies; static json_t *denomination_key_validity_withdraw_inconsistencies; /** - * Array of reports about reserve balance insufficient inconsitencies. + * Array of reports about reserve balance insufficient inconsistencies. */ static json_t *report_reserve_balance_insufficient_inconsistencies; /** - * Array of reports about purse balance insufficient inconsitencies. + * Array of reports about purse balance insufficient inconsistencies. */ static json_t *report_purse_balance_insufficient_inconsistencies; @@ -94,7 +94,7 @@ static struct TALER_Amount total_balance_summary_delta_plus; static struct TALER_Amount total_balance_summary_delta_minus; /** - * Array of reports about reserve's not being closed inconsitencies. + * Array of reports about reserve's not being closed inconsistencies. */ static json_t *report_reserve_not_closed_inconsistencies; diff --git a/src/auditor/taler-helper-auditor-wire.c b/src/auditor/taler-helper-auditor-wire.c index 2d2bdbcc2..de5acc48a 100644 --- a/src/auditor/taler-helper-auditor-wire.c +++ b/src/auditor/taler-helper-auditor-wire.c @@ -186,12 +186,12 @@ static struct TALER_AUDITORDB_WireProgressPoint pp; static struct TALER_AUDITORDB_WireProgressPoint start_pp; /** - * Array of reports about row inconsitencies in wire_out table. + * Array of reports about row inconsistencies in wire_out table. */ static json_t *report_wire_out_inconsistencies; /** - * Array of reports about row inconsitencies in reserves_in table. + * Array of reports about row inconsistencies in reserves_in table. */ static json_t *report_reserve_in_inconsistencies; @@ -1117,8 +1117,9 @@ generate_report (void *cls, * and have not yet seen a wire transfer. * * @param cls closure, points to a `struct ReportMissingWireContext` + * @param batch_deposit_serial_id row in the database for which the wire transfer is missing * @param total_amount value of the missing deposits, including fee - * @param payto_uri where should the funds be wired + * @param wire_target_h_payto hash of payto-URI where the funds should have been wired * @param deadline what was the earliest requested wire transfer deadline */ static void @@ -1385,7 +1386,7 @@ wire_out_cb (void *cls, { /* Wire transfer was not made (yet) at all (but would have been justified), so the entire amount is missing / still to be done. - This is moderately harmless, it might just be that the aggreator + This is moderately harmless, it might just be that the aggregator has not yet fully caught up with the transfers it should do. */ TALER_ARL_report ( report_wire_out_inconsistencies, diff --git a/src/auditordb/pg_select_pending_deposits.h b/src/auditordb/pg_select_pending_deposits.h index bbf3e843a..7e085304d 100644 --- a/src/auditordb/pg_select_pending_deposits.h +++ b/src/auditordb/pg_select_pending_deposits.h @@ -30,6 +30,8 @@ * Return (batch) deposits for which we have not yet * seen the required wire transfer. * + * @param cls closure + * @param master_pub master public key of the exchange * @param deadline only return up to this deadline * @param cb function to call on each entry * @param cb_cls closure for @a cb diff --git a/src/bank-lib/fakebank.h b/src/bank-lib/fakebank.h index 6310231b9..a9d61d8b1 100644 --- a/src/bank-lib/fakebank.h +++ b/src/bank-lib/fakebank.h @@ -551,7 +551,7 @@ struct TALER_FAKEBANK_Handle /** * Hashmap of reserve public keys to * `struct Transaction` with that reserve public - * key. Used to prevent public-key re-use. + * key. Used to prevent public-key reuse. */ struct GNUNET_CONTAINER_MultiPeerMap *rpubs; diff --git a/src/bank-lib/fakebank_bank_get_withdrawals.h b/src/bank-lib/fakebank_bank_get_withdrawals.h index a753dcee8..62a96866c 100644 --- a/src/bank-lib/fakebank_bank_get_withdrawals.h +++ b/src/bank-lib/fakebank_bank_get_withdrawals.h @@ -17,7 +17,7 @@ see <http://www.gnu.org/licenses/> */ /** - * @file bank-lib/fakebank_bank_get_accounts_withdrawals.h + * @file bank-lib/fakebank_bank_get_withdrawals.h * @brief implements the Taler Bank API "GET /accounts/ACC/withdrawals/WID" handler * @author Christian Grothoff <christian@grothoff.org> */ diff --git a/src/bank-lib/fakebank_bank_post_accounts_withdrawals.c b/src/bank-lib/fakebank_bank_post_accounts_withdrawals.c index 10a241fa8..7fbb93352 100644 --- a/src/bank-lib/fakebank_bank_post_accounts_withdrawals.c +++ b/src/bank-lib/fakebank_bank_post_accounts_withdrawals.c @@ -38,7 +38,7 @@ * @param h our fakebank handle * @param connection the connection * @param account_name name of the account - * @param amount amont to withdraw + * @param amount amount to withdraw * @return MHD result code */ static MHD_RESULT diff --git a/src/bank-lib/fakebank_bank_post_withdrawals_abort.h b/src/bank-lib/fakebank_bank_post_withdrawals_abort.h index fcc94e201..920b0b802 100644 --- a/src/bank-lib/fakebank_bank_post_withdrawals_abort.h +++ b/src/bank-lib/fakebank_bank_post_withdrawals_abort.h @@ -17,7 +17,7 @@ see <http://www.gnu.org/licenses/> */ /** - * @file bank-lib/fakebank_bank_post_accounts_withdrawals_abort.h + * @file bank-lib/fakebank_bank_post_withdrawals_abort.h * @brief implement bank API withdrawals /abort endpoint * @author Christian Grothoff <christian@grothoff.org> */ diff --git a/src/bank-lib/fakebank_bank_post_withdrawals_confirm.c b/src/bank-lib/fakebank_bank_post_withdrawals_confirm.c index 90aaf5e2c..2fa67c970 100644 --- a/src/bank-lib/fakebank_bank_post_withdrawals_confirm.c +++ b/src/bank-lib/fakebank_bank_post_withdrawals_confirm.c @@ -34,14 +34,6 @@ #include "fakebank_common_make_admin_transfer.h" -/** - * Handle POST /withdrawals/{withdrawal_id}/confirm request. - * - * @param h our fakebank handle - * @param connection the connection - * @param withdrawal_id the withdrawal operation identifier - * @return MHD result code - */ MHD_RESULT TALER_FAKEBANK_bank_withdrawals_confirm_ ( struct TALER_FAKEBANK_Handle *h, diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c index 1cde58164..67e089627 100644 --- a/src/exchange/taler-exchange-httpd.c +++ b/src/exchange/taler-exchange-httpd.c @@ -390,7 +390,6 @@ handle_post_coins (struct TEH_RequestContext *rc, * EdDSA key of the coin and demultiplexes based on $OP. * * @param rc request context - * @param root uploaded JSON data * @param args array of additional options * @return MHD result code */ diff --git a/src/exchange/taler-exchange-httpd_age-withdraw.c b/src/exchange/taler-exchange-httpd_age-withdraw.c index 1759bc552..939e0f76d 100644 --- a/src/exchange/taler-exchange-httpd_age-withdraw.c +++ b/src/exchange/taler-exchange-httpd_age-withdraw.c @@ -71,7 +71,7 @@ struct AgeWithdrawContext /** * #num_coins * #kappa hashes of blinded coin planchets. */ - struct TALER_BlindedPlanchet (*coin_evs)[TALER_CNC_KAPPA]; + struct TALER_BlindedPlanchet (*coin_evs) [ TALER_CNC_KAPPA]; /** * #num_coins hashes of the denominations from which the coins are withdrawn. @@ -310,7 +310,7 @@ EXIT: * @param ksh The handle to the current state of (denomination) keys in the exchange * @param denom_h Hash of the denomination key to check * @param[out] pdk On success, will contain the denomination key details - * @param[out] result On failure, an MHD-response will be qeued and result will be set to accordingly + * @param[out] result On failure, an MHD-response will be queued and result will be set to accordingly * @return true on success (denomination valid), false otherwise */ static bool @@ -409,7 +409,7 @@ are_denominations_valid ( struct MHD_Connection *connection, uint32_t len, const struct TALER_DenominationHashP *denom_hs, - const struct TALER_BlindedPlanchet (*coin_evs)[TALER_CNC_KAPPA], + const struct TALER_BlindedPlanchet (*coin_evs) [ TALER_CNC_KAPPA], uint64_t **denom_serials, struct TALER_Amount *amount_with_fee, MHD_RESULT *result) @@ -450,7 +450,7 @@ are_denominations_valid ( return GNUNET_SYSERR; /* Ensure the ciphers from the planchets match the denominations' */ - for (uint8_t k=0; k < TALER_CNC_KAPPA; k++) + for (uint8_t k = 0; k < TALER_CNC_KAPPA; k++) { if (dk->denom_pub.bsign_pub_key->cipher != coin_evs[i][k].blinded_message->cipher) diff --git a/src/exchange/taler-exchange-httpd_batch-deposit.c b/src/exchange/taler-exchange-httpd_batch-deposit.c index baf2b964d..9f66a99a4 100644 --- a/src/exchange/taler-exchange-httpd_batch-deposit.c +++ b/src/exchange/taler-exchange-httpd_batch-deposit.c @@ -28,6 +28,7 @@ #include <jansson.h> #include <microhttpd.h> #include <pthread.h> +#include "taler_extensions_policy.h" #include "taler_json_lib.h" #include "taler_mhd_lib.h" #include "taler-exchange-httpd_batch-deposit.h" @@ -168,7 +169,7 @@ batch_deposit_transaction (void *cls, { struct BatchDepositContext *dc = cls; const struct TALER_EXCHANGEDB_BatchDeposit *bd = &dc->bd; - enum GNUNET_DB_QueryStatus qs = GNUNET_SYSERR; + enum GNUNET_DB_QueryStatus qs = GNUNET_DB_STATUS_HARD_ERROR; uint32_t bad_balance_coin_index = UINT32_MAX; bool balance_ok; bool in_conflict; @@ -185,8 +186,9 @@ batch_deposit_transaction (void *cls, &dc->policy_details.fulfillment_state); if (qs < 0) return qs; - /* FIXME-Oec: dc->bd.policy_blocked not initialized, - likely should be set based on fulfillment_state!?*/ + + dc->bd.policy_blocked = + dc->policy_details.fulfillment_state != TALER_PolicyFulfillmentSuccess; } /* FIXME: replace by batch insert! */ @@ -523,9 +525,7 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc, return MHD_YES; /* failure */ } } - GNUNET_assert (GNUNET_OK == - TALER_amount_set_zero (TEH_currency, - &dc.policy_details.accumulated_total)); + /* validate merchant's wire details (as far as we can) */ { char *emsg; @@ -578,13 +578,18 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc, if (GNUNET_OK != TALER_extensions_create_policy_details ( + TEH_currency, dc.policy_json, &dc.policy_details, &error_hint)) + { + GNUNET_break_op (0); + GNUNET_JSON_parse_free (spec); return TALER_MHD_reply_with_error (connection, MHD_HTTP_BAD_REQUEST, TALER_EC_EXCHANGE_DEPOSITS_POLICY_NOT_ACCEPTED, error_hint); + } TALER_deposit_policy_hash (dc.policy_json, &dc.h_policy); diff --git a/src/exchange/taler-exchange-httpd_batch-withdraw.c b/src/exchange/taler-exchange-httpd_batch-withdraw.c index 19a9cacf1..e296f31f8 100644 --- a/src/exchange/taler-exchange-httpd_batch-withdraw.c +++ b/src/exchange/taler-exchange-httpd_batch-withdraw.c @@ -75,7 +75,7 @@ struct BatchWithdrawContext { /** - * Public key of the reserv. + * Public key of the reserve. */ const struct TALER_ReservePublicKeyP *reserve_pub; diff --git a/src/exchange/taler-exchange-httpd_extensions.c b/src/exchange/taler-exchange-httpd_extensions.c index 1ee573b0f..dd0fada76 100644 --- a/src/exchange/taler-exchange-httpd_extensions.c +++ b/src/exchange/taler-exchange-httpd_extensions.c @@ -357,44 +357,39 @@ TEH_extensions_post_handler ( } + if (GNUNET_OK != + ext->policy_post_handler (root, + &args[1], + policy_details, + policy_details_count, + &output)) { - enum GNUNET_GenericReturnValue ret; - - ret = ext->policy_post_handler (root, - &args[1], - policy_details, - policy_details_count, - &output); - - if (GNUNET_OK != ret) - { - TALER_MHD_reply_json_steal ( - rc->connection, - output, - MHD_HTTP_BAD_REQUEST); - } + return TALER_MHD_reply_json_steal ( + rc->connection, + output, + MHD_HTTP_BAD_REQUEST); + } - /* execute fulfillment transaction */ + /* execute fulfillment transaction */ + { + MHD_RESULT mhd_ret; + struct TALER_PolicyFulfillmentTransactionData fulfillment = { + .proof = root, + .timestamp = GNUNET_TIME_timestamp_get (), + .details = policy_details, + .details_count = policy_details_count + }; + + if (GNUNET_OK != + TEH_DB_run_transaction (rc->connection, + "execute policy fulfillment", + TEH_MT_REQUEST_POLICY_FULFILLMENT, + &mhd_ret, + &policy_fulfillment_transaction, + &fulfillment)) { - MHD_RESULT mhd_ret; - struct TALER_PolicyFulfillmentTransactionData fulfillment = { - .proof = root, - .timestamp = GNUNET_TIME_timestamp_get (), - .details = policy_details, - .details_count = policy_details_count - }; - - if (GNUNET_OK != - TEH_DB_run_transaction (rc->connection, - "execute policy fulfillment", - TEH_MT_REQUEST_POLICY_FULFILLMENT, - &mhd_ret, - &policy_fulfillment_transaction, - &fulfillment)) - { - json_decref (output); - return mhd_ret; - } + json_decref (output); + return mhd_ret; } } diff --git a/src/exchange/taler-exchange-httpd_melt.c b/src/exchange/taler-exchange-httpd_melt.c index f8aea95c5..b31078f00 100644 --- a/src/exchange/taler-exchange-httpd_melt.c +++ b/src/exchange/taler-exchange-httpd_melt.c @@ -288,7 +288,7 @@ static MHD_RESULT check_melt_valid (struct MHD_Connection *connection, struct MeltContext *rmc) { - /* Baseline: check if deposits/refreshs are generally + /* Baseline: check if deposits/refreshes are generally simply still allowed for this denomination */ struct TEH_DenominationKey *dk; MHD_RESULT mret; diff --git a/src/exchangedb/0002-batch_deposits.sql b/src/exchangedb/0002-batch_deposits.sql index af0764aa7..71a4b4205 100644 --- a/src/exchangedb/0002-batch_deposits.sql +++ b/src/exchangedb/0002-batch_deposits.sql @@ -111,9 +111,6 @@ BEGIN ' PRIMARY KEY (batch_deposit_serial_id) ' ',ADD CONSTRAINT ' || table_name || '_merchant_pub_h_contract_terms' ' UNIQUE (shard, merchant_pub, h_contract_terms)' - ',ADD CONSTRAINT ' || table_name || '_foreign_policy_details' - ' FOREIGN KEY (policy_details_serial_id) ' - ' REFERENCES policy_details (policy_details_serial_id) ON DELETE RESTRICT' ); EXECUTE FORMAT ( 'CREATE INDEX ' || table_name || '_by_ready ' @@ -133,6 +130,22 @@ BEGIN END $$; +CREATE OR REPLACE FUNCTION foreign_table_batch_deposits() +RETURNS VOID +LANGUAGE plpgsql +AS $$ +DECLARE + table_name TEXT DEFAULT 'batch_deposits'; +BEGIN + EXECUTE FORMAT ( + 'ALTER TABLE ' || table_name || + ' ADD CONSTRAINT ' || table_name || '_foreign_policy_details' + ' FOREIGN KEY (policy_details_serial_id) ' + ' REFERENCES policy_details (policy_details_serial_id) ON DELETE RESTRICT' + ); +END +$$; + INSERT INTO exchange_tables (name @@ -150,5 +163,10 @@ INSERT INTO exchange_tables ,'exchange-0002' ,'constrain' ,TRUE + ,FALSE), + ('batch_deposits' + ,'exchange-0002' + ,'foreign' + ,TRUE ,FALSE) ; diff --git a/src/exchangedb/0002-policy_details.sql b/src/exchangedb/0002-policy_details.sql index 6972dd7b0..3acbb5c10 100644 --- a/src/exchangedb/0002-policy_details.sql +++ b/src/exchangedb/0002-policy_details.sql @@ -14,42 +14,162 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- --- FIXME-Oec: this table should be sharded! - -CREATE TABLE policy_details - (policy_details_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE - ,policy_hash_code BYTEA PRIMARY KEY CHECK(LENGTH(policy_hash_code)=16) - ,policy_json TEXT - ,deadline INT8 NOT NULL - ,commitment taler_amount NOT NULL - ,accumulated_total taler_amount NOT NULL - ,fee taler_amount NOT NULL - ,transferable taler_amount NOT NULL - ,fulfillment_state SMALLINT NOT NULL CHECK(fulfillment_state between 0 and 5) - ,fulfillment_id BIGINT NULL REFERENCES policy_fulfillments (fulfillment_id) ON DELETE CASCADE - ); -COMMENT ON TABLE policy_details - IS 'Policies that were provided with deposits via policy extensions.'; -COMMENT ON COLUMN policy_details.policy_hash_code - IS 'ID (GNUNET_HashCode) that identifies a policy. Will be calculated by the policy extension based on the content'; -COMMENT ON COLUMN policy_details.policy_json - IS 'JSON object with options set that the exchange needs to consider when executing a deposit. Supported details depend on the policy extensions supported by the exchange.'; -COMMENT ON COLUMN policy_details.deadline - IS 'Deadline until the policy must be marked as fulfilled (maybe "forever")'; -COMMENT ON COLUMN policy_details.commitment - IS 'The amount that this policy commits to. Invariant: commitment >= fee'; -COMMENT ON COLUMN policy_details.accumulated_total - IS 'The sum of all contributions of all deposit that reference this policy. Invariant: The fulfilment_state must be Insufficient as long as accumulated_total < commitment'; -COMMENT ON COLUMN policy_details.fee - IS 'The fee for this policy, due when the policy is fulfilled or timed out'; -COMMENT ON COLUMN policy_details.transferable - IS 'The amount that on fulfillment or timeout will be transferred to the payto-URI''s of the corresponding deposit''s. The policy fees must have been already deducted from it. Invariant: fee+transferable <= accumulated_total. The remaining amount (accumulated_total - fee - transferable) can be refreshed by the owner of the coins when the state is Timeout or Success.'; -COMMENT ON COLUMN policy_details.fulfillment_state - IS 'State of the fulfillment: +-- @author: Özgür Kesim + +CREATE FUNCTION create_table_policy_details( + IN partition_suffix TEXT DEFAULT NULL +) +RETURNS VOID +LANGUAGE plpgsql +AS $$ +DECLARE + table_name TEXT DEFAULT 'policy_details'; +BEGIN + PERFORM create_partitioned_table( + 'CREATE TABLE %I ' + '(policy_details_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY' + ',policy_hash_code gnunet_hashcode NOT NULL' + ',policy_json TEXT NOT NULL' + ',deadline INT8 NOT NULL' + ',commitment taler_amount NOT NULL' + ',accumulated_total taler_amount NOT NULL' + ',fee taler_amount NOT NULL' + ',transferable taler_amount NOT NULL' + ',fulfillment_state SMALLINT NOT NULL CHECK(fulfillment_state between 0 and 5)' + ',h_fulfillment_proof gnunet_hashcode' + ') %s;' + ,table_name + ,'PARTITION BY HASH (h_fulfillment_proof)' + ,partition_suffix + ); + PERFORM comment_partitioned_table( + 'Policies that were provided with deposits via policy extensions.' + ,table_name + ,partition_suffix + ); + PERFORM comment_partitioned_column( + 'ID (GNUNET_HashCode) that identifies a policy. Will be calculated by the policy extension based on the content' + ,'policy_hash_code' + ,table_name + ,partition_suffix + ); + PERFORM comment_partitioned_column( + 'JSON object with options set that the exchange needs to consider when executing a deposit. Supported details depend on the policy extensions supported by the exchange.' + ,'policy_json' + ,table_name + ,partition_suffix + ); + PERFORM comment_partitioned_column( + 'Deadline until the policy must be marked as fulfilled (maybe "forever")' + ,'deadline' + ,table_name + ,partition_suffix + ); + PERFORM comment_partitioned_column( + 'The amount that this policy commits to. Invariant: commitment >= fee' + ,'commitment' + ,table_name + ,partition_suffix + ); + PERFORM comment_partitioned_column( + 'The sum of all contributions of all deposit that reference this policy. Invariant: The fulfilment_state must be Insufficient as long as accumulated_total < commitment' + ,'accumulated_total' + ,table_name + ,partition_suffix + ); + PERFORM comment_partitioned_column( + 'The fee for this policy, due when the policy is fulfilled or timed out' + ,'fee' + ,table_name + ,partition_suffix + ); + PERFORM comment_partitioned_column( + 'The amount that on fulfillment or timeout will be transferred to the payto-URI''s of the corresponding deposit''s. The policy fees must have been already deducted from it. Invariant: fee+transferable <= accumulated_total. The remaining amount (accumulated_total - fee - transferable) can be refreshed by the owner of the coins when the state is Timeout or Success.' + ,'transferable' + ,table_name + ,partition_suffix + ); + PERFORM comment_partitioned_column( + 'State of the fulfillment: - 0 (Failure) - 1 (Insufficient) - 2 (Ready) - 4 (Success) - - 5 (Timeout)'; -COMMENT ON COLUMN policy_details.fulfillment_id - IS 'Reference to the proof of the fulfillment of this policy, if it exists. Invariant: If not NULL, this entry''s .hash_code MUST be part of the corresponding policy_fulfillments.policy_hash_codes array.'; + - 5 (Timeout)' + ,'fulfillment_state' + ,table_name + ,partition_suffix + ); + PERFORM comment_partitioned_column( + 'Reference to the proof of the fulfillment of this policy, if it exists. Invariant: If not NULL, this entry''s .hash_code MUST be part of the corresponding policy_fulfillments.policy_hash_codes array.' + ,'h_fulfillment_proof' + ,table_name + ,partition_suffix + ); +END +$$; + +COMMENT ON FUNCTION create_table_policy_details + IS 'Creates the policy_details table'; + + + + +CREATE FUNCTION constrain_table_policy_details( + IN partition_suffix TEXT +) +RETURNS VOID +LANGUAGE plpgsql +AS $$ +DECLARE + partition_name TEXT; +BEGIN + partition_name = concat_ws('_', 'policy_details', partition_suffix); + + EXECUTE FORMAT ( + 'ALTER TABLE ' || partition_name || + ' ADD CONSTRAINT ' || partition_name || '_unique_serial_id ' + ' UNIQUE (policy_details_serial_id)' + ); + + EXECUTE FORMAT ( + 'ALTER TABLE ' || partition_name || + ' ADD CONSTRAINT ' || partition_name || '_unique_hash_fulfillment_proof ' + ' UNIQUE (policy_hash_code, h_fulfillment_proof)' + ); + + EXECUTE FORMAT ( + 'CREATE INDEX ' || partition_name || '_policy_hash_code' + ' ON ' || partition_name || + ' (policy_hash_code);' + ); +END +$$; + +CREATE OR REPLACE FUNCTION foreign_table_policy_details() +RETURNS VOID +LANGUAGE plpgsql +AS $$ +DECLARE + table_name TEXT DEFAULT 'policy_details'; +BEGIN + EXECUTE FORMAT ( + 'ALTER TABLE ' || table_name || + ' ADD CONSTRAINT ' || table_name || '_foreign_policy_fulfillments' + ' FOREIGN KEY (h_fulfillment_proof) ' + ' REFERENCES policy_fulfillments (h_fulfillment_proof) ON DELETE RESTRICT' + ); +END +$$; + + +INSERT INTO exchange_tables + (name + ,version + ,action + ,partitioned + ,by_range) +VALUES + ('policy_details', 'exchange-0002', 'create', TRUE ,FALSE), + ('policy_details', 'exchange-0002', 'constrain', TRUE ,FALSE), + ('policy_details', 'exchange-0002', 'foreign', TRUE ,FALSE); diff --git a/src/exchangedb/0002-policy_fulfillments.sql b/src/exchangedb/0002-policy_fulfillments.sql index 28dd619e0..c00947019 100644 --- a/src/exchangedb/0002-policy_fulfillments.sql +++ b/src/exchangedb/0002-policy_fulfillments.sql @@ -14,22 +14,88 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- --- FIXME-Oec: this table should be sharded! +-- @author: Özgür Kesim -CREATE TABLE policy_fulfillments - (fulfillment_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY - ,fulfillment_timestamp INT8 NOT NULL - ,fulfillment_proof TEXT - ,h_fulfillment_proof BYTEA NOT NULL CHECK(LENGTH(h_fulfillment_proof) = 64) UNIQUE - ,policy_hash_codes BYTEA NOT NULL CHECK(0 = MOD(LENGTH(policy_hash_codes), 16)) +CREATE FUNCTION create_table_policy_fulfillments( + IN partition_suffix TEXT DEFAULT NULL +) +RETURNS VOID +LANGUAGE plpgsql +AS $$ +DECLARE + table_name TEXT DEFAULT 'policy_fulfillments'; +BEGIN + PERFORM create_partitioned_table( + 'CREATE TABLE %I ' + '(h_fulfillment_proof gnunet_hashcode PRIMARY KEY' + ',fulfillment_id BIGINT GENERATED BY DEFAULT AS IDENTITY' + ',fulfillment_timestamp INT8 NOT NULL' + ',fulfillment_proof TEXT' + ',policy_hash_codes gnunet_hashcode[] NOT NULL' + ') %s ;' + ,table_name + ,'PARTITION BY HASH (h_fulfillment_proof)' + ,partition_suffix ); -COMMENT ON TABLE policy_fulfillments - IS 'Proofs of fulfillment of policies that were set in deposits'; -COMMENT ON COLUMN policy_fulfillments.fulfillment_timestamp - IS 'Timestamp of the arrival of a proof of fulfillment'; -COMMENT ON COLUMN policy_fulfillments.fulfillment_proof - IS 'JSON object with a proof of the fulfillment of a policy. Supported details depend on the policy extensions supported by the exchange.'; -COMMENT ON COLUMN policy_fulfillments.h_fulfillment_proof - IS 'Hash of the fulfillment_proof'; -COMMENT ON COLUMN policy_fulfillments.policy_hash_codes - IS 'Concatenation of the policy_hash_code of all policy_details that are fulfilled by this proof'; + PERFORM comment_partitioned_table( + 'Proofs of fulfillment of policies that were set in deposits' + ,table_name + ,partition_suffix + ); + PERFORM comment_partitioned_column( + 'Timestamp of the arrival of a proof of fulfillment' + ,'fulfillment_timestamp' + ,table_name + ,partition_suffix + ); + PERFORM comment_partitioned_column( + 'JSON object with a proof of the fulfillment of a policy. Supported details depend on the policy extensions supported by the exchange.' + ,'fulfillment_proof' + ,table_name + ,partition_suffix + ); + PERFORM comment_partitioned_column( + 'Hash of the fulfillment_proof' + ,'h_fulfillment_proof' + ,table_name + ,partition_suffix + ); + PERFORM comment_partitioned_column( + 'Array of the policy_hash_code''s of all policy_details that are fulfilled by this proof' + ,'policy_hash_codes' + ,table_name + ,partition_suffix + ); +END +$$; + +COMMENT ON FUNCTION create_table_policy_fulfillments + IS 'Creates the policy_fulfillments table'; + +CREATE FUNCTION constrain_table_policy_fulfillments( + IN partition_suffix TEXT +) +RETURNS VOID +LANGUAGE plpgsql +AS $$ +DECLARE + partition_name TEXT; +BEGIN + partition_name = concat_ws('_', 'policy_fulfillments', partition_suffix); + + EXECUTE FORMAT ( + 'ALTER TABLE ' || partition_name || + ' ADD CONSTRAINT ' || partition_name || '_serial_id ' + ' UNIQUE (h_fulfillment_proof, fulfillment_id)' + ); +END +$$; +INSERT INTO exchange_tables + (name + ,version + ,action + ,partitioned + ,by_range) +VALUES + ('policy_fulfillments', 'exchange-0002', 'create', TRUE ,FALSE), + ('policy_fulfillments', 'exchange-0002', 'constrain', TRUE ,FALSE); diff --git a/src/exchangedb/exchange-0002.sql.in b/src/exchangedb/exchange-0002.sql.in index e209d5504..ab13b28af 100644 --- a/src/exchangedb/exchange-0002.sql.in +++ b/src/exchangedb/exchange-0002.sql.in @@ -19,6 +19,10 @@ BEGIN; SELECT _v.register_patch('exchange-0002', NULL, NULL); SET search_path TO exchange; +CREATE DOMAIN gnunet_hashcode + AS BYTEA + CHECK(LENGTH(VALUE) = 32); + CREATE TYPE taler_amount AS (val INT8 @@ -59,6 +63,8 @@ COMMENT ON TYPE exchange_do_select_deposits_missing_wire_return_type #include "0002-exchange_sign_keys.sql" #include "0002-signkey_revocations.sql" #include "0002-extensions.sql" +#include "0002-policy_fulfillments.sql" +#include "0002-policy_details.sql" #include "0002-profit_drains.sql" #include "0002-legitimization_processes.sql" #include "0002-legitimization_requirements.sql" @@ -96,8 +102,6 @@ COMMENT ON TYPE exchange_do_select_deposits_missing_wire_return_type #include "0002-wad_in_entries.sql" #include "0002-wads_out.sql" #include "0002-wad_out_entries.sql" -#include "0002-policy_fulfillments.sql" -#include "0002-policy_details.sql" #include "0002-work_shards.sql" #include "0002-revolving_work_shards.sql" #include "0002-partners.sql" diff --git a/src/exchangedb/exchangedb-postgres.conf b/src/exchangedb/exchangedb-postgres.conf index e481940ce..3e0cb4ffb 100644 --- a/src/exchangedb/exchangedb-postgres.conf +++ b/src/exchangedb/exchangedb-postgres.conf @@ -1,5 +1,5 @@ [exchangedb-postgres] -CONFIG = "postgres:///taler" +CONFIG = "postgres:///taler-exchange" # Where are the SQL files to setup our tables? # Important: this MUST end with a "/"! diff --git a/src/exchangedb/pg_select_aggregations_above_serial.h b/src/exchangedb/pg_select_aggregations_above_serial.h index 3950d11fb..2883b19f2 100644 --- a/src/exchangedb/pg_select_aggregations_above_serial.h +++ b/src/exchangedb/pg_select_aggregations_above_serial.h @@ -31,7 +31,7 @@ * above a given @a min_tracking_serial_id. * * @param cls closure - * @param min_tracking_serial_id only return entries stricly above this row (and in order) + * @param min_tracking_serial_id only return entries strictly above this row (and in order) * @param cb function to call on all such aggregations * @param cb_cls closure for @a cb * @return transaction status code diff --git a/src/extensions/extensions.c b/src/extensions/extensions.c index fbbe874fb..999e9317a 100644 --- a/src/extensions/extensions.c +++ b/src/extensions/extensions.c @@ -19,6 +19,7 @@ * @author Özgür Kesim */ #include "platform.h" +#include "taler_extensions_policy.h" #include "taler_util.h" #include "taler_signatures.h" #include "taler_extensions.h" @@ -366,6 +367,7 @@ TALER_extensions_load_manifests ( */ static char *fulfillment2str[] = { + [TALER_PolicyFulfillmentInitial] = "<init>", [TALER_PolicyFulfillmentReady] = "Ready", [TALER_PolicyFulfillmentSuccess] = "Success", [TALER_PolicyFulfillmentFailure] = "Failure", @@ -384,6 +386,7 @@ TALER_policy_fulfillment_state_str ( enum GNUNET_GenericReturnValue TALER_extensions_create_policy_details ( + const char *currency, const json_t *policy_options, struct TALER_PolicyDetails *details, const char **error_hint) @@ -427,8 +430,18 @@ TALER_extensions_create_policy_details ( return GNUNET_NO; } + /* Set state fields in the policy details to initial values. */ + GNUNET_assert (GNUNET_OK == + TALER_amount_set_zero (currency, + &details->accumulated_total)); + GNUNET_assert (GNUNET_OK == + TALER_amount_set_zero (currency, + &details->policy_fee)); details->deadline = GNUNET_TIME_UNIT_FOREVER_TS; - ret = extension->create_policy_details (policy_options, + details->fulfillment_state = TALER_PolicyFulfillmentInitial; + details->no_policy_fulfillment_id = true; + ret = extension->create_policy_details (currency, + policy_options, details, error_hint); return ret; diff --git a/src/include/taler_auditordb_plugin.h b/src/include/taler_auditordb_plugin.h index 31e6723a5..b83d6316c 100644 --- a/src/include/taler_auditordb_plugin.h +++ b/src/include/taler_auditordb_plugin.h @@ -628,7 +628,7 @@ typedef enum GNUNET_GenericReturnValue * @param batch_deposit_serial_id where in the table are we * @param total_amount value of all missing deposits, including fees * @param wire_target_h_payto hash of the recipient account's payto URI - * @param earliest_deadline what was the earliest requested wire transfer deadline + * @param deadline what was the earliest requested wire transfer deadline */ typedef void (*TALER_AUDITORDB_WireMissingCallback)( diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index cecd0562e..0b80ff071 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -1717,7 +1717,7 @@ TALER_test_coin_valid (const struct TALER_CoinPublicInfo *coin_public_info, * Compute the hash of a blinded coin. * * @param blinded_planchet blinded planchet - * @param denom_hash hash of the denomination publick key + * @param denom_hash hash of the denomination public key * @param[out] bch where to write the hash * @return #GNUNET_OK when successful, #GNUNET_SYSERR if an internal error occurred */ @@ -2324,7 +2324,7 @@ struct TALER_CRYPTO_RsaDenominationHelper; * @param validity_duration how long does the key remain available for signing; * zero if the key has been revoked or purged * @param h_rsa hash of the RSA @a denom_pub that is available (or was purged) - * @param denom_pub the public key itself, NULL if the key was revoked or purged + * @param bs_pub the public key itself, NULL if the key was revoked or purged * @param sm_pub public key of the security module, NULL if the key was revoked or purged * @param sm_sig signature from the security module, NULL if the key was revoked or purged * The signature was already verified against @a sm_pub. @@ -4682,7 +4682,7 @@ TALER_exchange_online_age_withdraw_confirmation_sign ( /** - * Verfiy an exchange age-withdraw confirmation + * Verify an exchange age-withdraw confirmation * * @param h_commitment Commitment over all n*kappa coin candidates from the original request to age-withdraw * @param noreveal_index The index returned by the exchange @@ -5727,7 +5727,7 @@ TALER_age_commitment_derive ( * * @param comm_proof The age commitment to be used for attestation. For successful attestation, it must contain the private key for the corresponding age group. * @param age Age (not age group) for which the an attestation should be done - * @param[out] attest Signature of the age with the appropriate key from the age commitment for the corresponding age group, if applicaple. + * @param[out] attest Signature of the age with the appropriate key from the age commitment for the corresponding age group, if applicable. * @return #GNUNET_OK on success, #GNUNET_NO when no attestation can be made for that age with the given commitment, #GNUNET_SYSERR otherwise */ enum GNUNET_GenericReturnValue @@ -5742,7 +5742,7 @@ TALER_age_commitment_attest ( * * @param commitment The age commitment that went into the attestation. Only the public keys are needed. * @param age Age (not age group) for which the an attestation should be done - * @param attest Signature of the age with the appropriate key from the age commitment for the corresponding age group, if applicaple. + * @param attest Signature of the age with the appropriate key from the age commitment for the corresponding age group, if applicable. * @return #GNUNET_OK when the attestation was successful, #GNUNET_NO no attestation couldn't be verified, #GNUNET_SYSERR otherwise */ enum GNUNET_GenericReturnValue @@ -5867,7 +5867,7 @@ struct TALER_DenominationGroup enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher; /** - * Age mask for the denomiation. + * Age mask for the denomination. */ struct TALER_AgeMask age_mask; diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index 7b9b1dd41..b2e513341 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -815,7 +815,7 @@ TALER_EXCHANGE_keys_incref (struct TALER_EXCHANGE_Keys *keys); /** - * Deccrement reference counter for @a keys. + * Decrement reference counter for @a keys. * Frees @a keys if reference counter becomes zero. * * @param[in,out] keys object to decrement reference counter for @@ -1767,7 +1767,6 @@ struct TALER_EXCHANGE_CoinsHistoryHandle; * @param dk denomination key of the coin * @param history JSON array with the coin's history * @param coin_pub public key of the coin - * @param currency currency of the coin * @param[out] total_in set to total amount credited to the coin in @a history * @param[out] total_out set to total amount debited to the coin in @a history * @param rlen length of the @a rhistory array @@ -1871,15 +1870,12 @@ typedef void * have to combine multiple partial coin histories * into one coherent history before calling this function. * - * @param keys /keys data of the exchange - * @param dk denomination key of the coin - * @param history JSON array with the coin's full history - * @param coin_pub public key of the coin - * @param currency currency of the coin - * @param[out] total_in set to total amount credited to the coin in @a history - * @param[out] total_out set to total amount debited to the coin in @a history - * @param len length of the @a rhistory - * @param[out] rhistory where to write the parsed @a history + * @param ctx context for managing request + * @param url base URL of the exchange + * @param coin_priv private key of the coin + * @param start_off offset from which on to request history + * @param cb function to call with results + * @param cb_cls closure for @a cb * @return #GNUNET_OK if @a history is valid, * #GNUNET_SYSERR if not */ @@ -1896,7 +1892,7 @@ TALER_EXCHANGE_coins_history ( /** * Cancel #TALER_EXCHANGE_coins_history() operation. * - * @param[in] rsh operation to chancel + * @param[in] rsh operation to cancel */ void TALER_EXCHANGE_coins_history_cancel ( @@ -2996,7 +2992,7 @@ typedef void * @param curl_ctx The curl context * @param exchange_url The base url of the exchange * @param keys The denomination keys from the exchange - * @param reserve_priv The pivate key to the reserve + * @param reserve_priv The private key to the reserve * @param num_coins The number of elements in @e coin_inputs * @param coin_inputs The input for the coins to withdraw * @param max_age The maximum age we commit to. diff --git a/src/include/taler_exchangedb_lib.h b/src/include/taler_exchangedb_lib.h index 17b01b0ad..d93cf9d6c 100644 --- a/src/include/taler_exchangedb_lib.h +++ b/src/include/taler_exchangedb_lib.h @@ -69,13 +69,13 @@ struct TALER_EXCHANGEDB_AccountInfo const char *method; /** - * true if this account is enabed to be debited + * true if this account is enabled to be debited * by the taler-exchange-aggregator. */ bool debit_enabled; /** - * true if this account is enabed to be credited by wallets + * true if this account is enabled to be credited by wallets * and needs to be watched by the taler-exchange-wirewatch. * Also, the account will only be included in /wire if credit * is enabled. diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index 704f8012a..6da278637 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -3401,7 +3401,7 @@ typedef void * @param batch_deposit_serial_id where in the table are we * @param total_amount value of all missing deposits, including fees * @param wire_target_h_payto hash of the recipient account's payto URI - * @param earliest_deadline what was the earliest requested wire transfer deadline + * @param deadline what was the earliest requested wire transfer deadline */ typedef void (*TALER_EXCHANGEDB_WireMissingCallback)( @@ -5530,7 +5530,7 @@ struct TALER_EXCHANGEDB_Plugin * above a given @a min_batch_deposit_serial_id. * * @param cls closure - * @param min_batch_deposit_serial_id only return entries stricly above this row (and in order) + * @param min_batch_deposit_serial_id only return entries strictly above this row (and in order) * @param cb function to call on all such deposits * @param cb_cls closure for @a cb * @return transaction status code @@ -5548,7 +5548,7 @@ struct TALER_EXCHANGEDB_Plugin * above a given @a min_tracking_serial_id. * * @param cls closure - * @param min_tracking_serial_id only return entries stricly above this row (and in order) + * @param min_tracking_serial_id only return entries strictly above this row (and in order) * @param cb function to call on all such aggregations * @param cb_cls closure for @a cb * @return transaction status code @@ -7088,7 +7088,7 @@ struct TALER_EXCHANGEDB_Plugin * @param new_status AML decision status * @param decision_time when was the decision made * @param justification human-readable text justifying the decision - * @param kyc_requirements specific KYC requiremnts being imposed + * @param kyc_requirements specific KYC requirements being imposed * @param requirements_row row in the KYC table for this process, 0 for none * @param decider_pub public key of the staff member * @param decider_sig signature of the staff member diff --git a/src/include/taler_extensions.h b/src/include/taler_extensions.h index fe1eac276..1eb567f72 100644 --- a/src/include/taler_extensions.h +++ b/src/include/taler_extensions.h @@ -162,6 +162,7 @@ struct TALER_Extension * (see https://docs.taler.net/core/api-exchange.html#deposit), this handler * will be called before the deposit transaction. * + * @param[in] currency Currency used in the exchange * @param[in] policy_json Details about the policy, provided by the client * during a deposit request. * @param[out] details On success, will contain the details to the policy, @@ -170,6 +171,7 @@ struct TALER_Extension * @return GNUNET_OK if the data was accepted by the extension. */ enum GNUNET_GenericReturnValue (*create_policy_details)( + const char *currency, const json_t *policy_json, struct TALER_PolicyDetails *details, const char **error_hint); diff --git a/src/include/taler_extensions_policy.h b/src/include/taler_extensions_policy.h index ecb4e2628..7750f58f1 100644 --- a/src/include/taler_extensions_policy.h +++ b/src/include/taler_extensions_policy.h @@ -31,21 +31,24 @@ */ enum TALER_PolicyFulfillmentState { + /* Initial state of an fulfillment, before any other state. */ + TALER_PolicyFulfillmentInitial = 0, + /* General error state of an fulfillment. */ - TALER_PolicyFulfillmentFailure = 0, + TALER_PolicyFulfillmentFailure = 1, /* The policy is not yet ready due to insufficient funding. More deposits are * necessary for it to become ready . */ - TALER_PolicyFulfillmentInsufficient = 1, + TALER_PolicyFulfillmentInsufficient = 2, /* The policy is funded and ready, pending */ - TALER_PolicyFulfillmentReady = 2, + TALER_PolicyFulfillmentReady = 3, /* Policy is provably fulfilled. */ - TALER_PolicyFulfillmentSuccess = 3, + TALER_PolicyFulfillmentSuccess = 4, /* Policy fulfillment has timed out */ - TALER_PolicyFulfillmentTimeout = 4, + TALER_PolicyFulfillmentTimeout = 5, TALER_PolicyFulfillmentStateCount = TALER_PolicyFulfillmentTimeout + 1 }; @@ -68,7 +71,7 @@ struct TALER_PolicyDetails /* Content of the policy in its original JSON form */ json_t *policy_json; - /* When the deadline is meat and the policy is still in "Ready" state, + /* When the deadline is met and the policy is still in "Ready" state, * a timeout-handler will transfer the amount * (total_amount - policy_fee - refreshable_amount) * to the payto-URI from the corresponding deposit. The value @@ -143,6 +146,7 @@ struct TALER_PolicyFulfillmentTransactionData /* * @brief Extracts policy details from the deposit's policy options and the policy extensions * + * @param[in] currency Currency used in the exchange * @param[in] policy_options JSON of the policy options from a deposit request * @param[out] details On GNUNET_OK, the parsed details * @param[out] error_hint On GNUNET_SYSERR, will contain a hint for the reason why it failed @@ -151,6 +155,7 @@ struct TALER_PolicyFulfillmentTransactionData */ enum GNUNET_GenericReturnValue TALER_extensions_create_policy_details ( + const char *currency, const json_t *policy_options, struct TALER_PolicyDetails *details, const char **error_hint); diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h index dc8061705..51fd17dd0 100644 --- a/src/include/taler_json_lib.h +++ b/src/include/taler_json_lib.h @@ -425,7 +425,7 @@ struct TALER_JSON_ProtocolVersion /** * Number of protocol versions this @e revision is * backwards-compatible with. Subtract this number - * from @a current to get the minimum protocol version + * from @e current to get the minimum protocol version * required from the client. */ unsigned int age; @@ -438,15 +438,14 @@ struct TALER_JSON_ProtocolVersion * encoding the version as "$CURRENT:$REVISION:$AGE". * * @param field name of the field (usually "version") - * @param[out] current protocol current to initialize - * @param[out] revision protocol revision to initialize - * @param[out] age protocol age to initialize + * @param[out] ver protocol versions to initialize * @return corresponding field spec */ struct GNUNET_JSON_Specification TALER_JSON_spec_version (const char *field, struct TALER_JSON_ProtocolVersion *ver); + /** * Generate a parser specification for a denomination public key of a given * cipher. diff --git a/src/include/taler_kyclogic_lib.h b/src/include/taler_kyclogic_lib.h index dfa4c58ac..4d0c18fa4 100644 --- a/src/include/taler_kyclogic_lib.h +++ b/src/include/taler_kyclogic_lib.h @@ -259,7 +259,7 @@ TALER_KYCLOGIC_check_satisfied (char **requirements, * Iterate over all thresholds that are applicable * to a particular type of @a event * - * @param event tresholds to look up + * @param event thresholds to look up * @param it function to call on each * @param it_cls closure for @a it */ diff --git a/src/include/taler_mhd_lib.h b/src/include/taler_mhd_lib.h index 60c5b209d..db6db05e8 100644 --- a/src/include/taler_mhd_lib.h +++ b/src/include/taler_mhd_lib.h @@ -481,7 +481,7 @@ TALER_MHD_parse_request_arg_timeout (struct MHD_Connection *connection, * * @param connection the MHD connection * @param name name of the query parameter - * @param[out] off set to the offet, unchanged if the + * @param[out] off set to the offset, unchanged if the * option was not given * @return #GNUNET_OK on success, * #GNUNET_NO if an error was returned on @a connection (caller should return #MHD_YES) and diff --git a/src/include/taler_pq_lib.h b/src/include/taler_pq_lib.h index 06e7d53ed..a529b4302 100644 --- a/src/include/taler_pq_lib.h +++ b/src/include/taler_pq_lib.h @@ -165,6 +165,19 @@ TALER_PQ_query_param_array_blinded_coin_hash ( /** + * Generate query parameter for an array of GNUNET_HashCode + * + * @param num number of elements in @e hash_codes + * @param hashes array of GNUNET_HashCode + * @param db context for the db-connection + */ +struct GNUNET_PQ_QueryParam +TALER_PQ_query_param_array_hash_code ( + size_t num, + const struct GNUNET_HashCode *hashes, + struct GNUNET_PQ_Context *db); + +/** * Generate query parameter for an array of mounts * * @param num of elements in @e amounts @@ -356,6 +369,22 @@ TALER_PQ_result_spec_array_denom_hash ( /** + * Array of GNUNET_HashCode + * + * @param db context of the database connection + * @param name name of the field in the table + * @param[out] num number of elements in @e denom_sigs + * @param[out] hashes where to store the result + * @return array entry for the result specification to use + */ +struct GNUNET_PQ_ResultSpec +TALER_PQ_result_spec_array_hash_code ( + struct GNUNET_PQ_Context *db, + const char *name, + size_t *num, + struct GNUNET_HashCode **hashes); + +/** * Array of amounts * * @param db context of the database connection diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h index a0a25832b..90f6ade88 100644 --- a/src/include/taler_testing_lib.h +++ b/src/include/taler_testing_lib.h @@ -1151,7 +1151,7 @@ TALER_TESTING_cmd_age_withdraw_reveal ( * @param amount how much we withdraw. * @param age if > 0, age restriction applies. * @param coin_ref reference to (withdraw/reveal) command of a coin - * from which we should re-use the private key + * from which we should reuse the private key * @param expected_response_code which HTTP response code * we expect from the exchange. * @return the withdraw command to be executed by the interpreter. @@ -1919,7 +1919,7 @@ struct TALER_TESTING_Timer struct GNUNET_TIME_Relative total_duration; /** - * Total time spend waiting for the *successful* exeuction + * Total time spend waiting for the *successful* execution * in all commands of this type. */ struct GNUNET_TIME_Relative success_latency; diff --git a/src/kyclogic/Makefile.am b/src/kyclogic/Makefile.am index 3e98a956f..d43d4a6c1 100644 --- a/src/kyclogic/Makefile.am +++ b/src/kyclogic/Makefile.am @@ -24,8 +24,7 @@ bin_SCRIPTS = \ EXTRA_DIST = \ $(pkgcfg_DATA) \ $(bin_SCRIPTS) \ - sample.conf \ - persona-sample-reply.json + sample.conf lib_LTLIBRARIES = \ libtalerkyclogic.la diff --git a/src/lib/auditor_api_deposit_confirmation.c b/src/lib/auditor_api_deposit_confirmation.c index 1e2ecc6cc..172a12ece 100644 --- a/src/lib/auditor_api_deposit_confirmation.c +++ b/src/lib/auditor_api_deposit_confirmation.c @@ -155,7 +155,8 @@ handle_deposit_confirmation_finished (void *cls, * @param wire_deadline by what time must the amount be wired to the merchant * @param refund_deadline date until which the merchant can issue a refund to the customer via the auditor (can be zero if refunds are not allowed); must not be after the @a wire_deadline * @param amount_without_fee the amount confirmed to be wired by the exchange to the merchant - * @param coin_pub coin’s public key + * @param num_coins number of coins involved + * @param coin_sigs array of @a num_coins coin signatures * @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests) * @param exchange_sig the signature made with purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT * @param exchange_pub the public key of the exchange that matches @a exchange_sig diff --git a/src/lib/exchange_api_age_withdraw.c b/src/lib/exchange_api_age_withdraw.c index efa605aea..e319332d1 100644 --- a/src/lib/exchange_api_age_withdraw.c +++ b/src/lib/exchange_api_age_withdraw.c @@ -161,7 +161,7 @@ struct TALER_EXCHANGE_AgeWithdrawBlindedHandle struct TALER_EXCHANGE_Keys *keys; /** - * The age mask, extacted from the denominations. + * The age mask, extracted from the denominations. * MUST be the same for all denominations * */ @@ -263,7 +263,7 @@ struct TALER_EXCHANGE_AgeWithdrawHandle struct TALER_EXCHANGE_Keys *keys; /** - * The age mask, extacted from the denominations. + * The age mask, extracted from the denominations. * MUST be the same for all denominations * */ diff --git a/src/lib/exchange_api_coins_history.c b/src/lib/exchange_api_coins_history.c index 6981fad5a..0999e185e 100644 --- a/src/lib/exchange_api_coins_history.c +++ b/src/lib/exchange_api_coins_history.c @@ -130,6 +130,7 @@ typedef enum GNUNET_GenericReturnValue * Handle deposit entry in the coin's history. * * @param[in,out] pc overall context + * @param[out] rh history entry to initialize * @param amount main amount of this operation * @param transaction JSON details for the operation * @return #GNUNET_SYSERR on error, @@ -226,6 +227,7 @@ help_deposit (struct CoinHistoryParseContext *pc, * Handle melt entry in the coin's history. * * @param[in,out] pc overall context + * @param[out] rh history entry to initialize * @param amount main amount of this operation * @param transaction JSON details for the operation * @return #GNUNET_SYSERR on error, @@ -294,6 +296,7 @@ help_melt (struct CoinHistoryParseContext *pc, * Handle refund entry in the coin's history. * * @param[in,out] pc overall context + * @param[out] rh history entry to initialize * @param amount main amount of this operation * @param transaction JSON details for the operation * @return #GNUNET_SYSERR on error, @@ -373,6 +376,7 @@ help_refund (struct CoinHistoryParseContext *pc, * Handle recoup entry in the coin's history. * * @param[in,out] pc overall context + * @param[out] rh history entry to initialize * @param amount main amount of this operation * @param transaction JSON details for the operation * @return #GNUNET_SYSERR on error, @@ -439,6 +443,7 @@ help_recoup (struct CoinHistoryParseContext *pc, * the value being credited to the old coin. * * @param[in,out] pc overall context + * @param[out] rh history entry to initialize * @param amount main amount of this operation * @param transaction JSON details for the operation * @return #GNUNET_SYSERR on error, @@ -505,6 +510,7 @@ help_recoup_refresh (struct CoinHistoryParseContext *pc, * the value being credited to the this coin. * * @param[in,out] pc overall context + * @param[out] rh history entry to initialize * @param amount main amount of this operation * @param transaction JSON details for the operation * @return #GNUNET_SYSERR on error, @@ -556,6 +562,7 @@ help_old_coin_recoup (struct CoinHistoryParseContext *pc, * Handle purse deposit entry in the coin's history. * * @param[in,out] pc overall context + * @param[out] rh history entry to initialize * @param amount main amount of this operation * @param transaction JSON details for the operation * @return #GNUNET_SYSERR on error, @@ -625,6 +632,7 @@ help_purse_deposit (struct CoinHistoryParseContext *pc, * Handle purse refund entry in the coin's history. * * @param[in,out] pc overall context + * @param[out] rh history entry to initialize * @param amount main amount of this operation * @param transaction JSON details for the operation * @return #GNUNET_SYSERR on error, @@ -686,6 +694,7 @@ help_purse_refund (struct CoinHistoryParseContext *pc, * Handle reserve deposit entry in the coin's history. * * @param[in,out] pc overall context + * @param[out] rh history entry to initialize * @param amount main amount of this operation * @param transaction JSON details for the operation * @return #GNUNET_SYSERR on error, diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c index ab3c387df..1d44ed34f 100644 --- a/src/lib/exchange_api_handle.c +++ b/src/lib/exchange_api_handle.c @@ -59,7 +59,7 @@ #define EXCHANGE_SERIALIZATION_FORMAT_VERSION 0 /** - * How far off do we allow key liftimes to be? + * How far off do we allow key lifetimes to be? */ #define LIFETIME_TOLERANCE GNUNET_TIME_UNIT_HOURS diff --git a/src/lib/exchange_api_purse_create_with_deposit.c b/src/lib/exchange_api_purse_create_with_deposit.c index 215b7847e..fc2499338 100644 --- a/src/lib/exchange_api_purse_create_with_deposit.c +++ b/src/lib/exchange_api_purse_create_with_deposit.c @@ -114,7 +114,7 @@ struct TALER_EXCHANGE_PurseCreateDepositHandle struct TALER_Amount purse_value_after_fees; /** - * Our encryped contract (if we had any). + * Our encrypted contract (if we had any). */ struct TALER_EncryptedContract econtract; diff --git a/src/pq/pq_common.h b/src/pq/pq_common.h index 6172c0bfb..735528ae1 100644 --- a/src/pq/pq_common.h +++ b/src/pq/pq_common.h @@ -44,6 +44,7 @@ enum TALER_PQ_ArrayType TALER_PQ_array_of_blinded_denom_sig, TALER_PQ_array_of_blinded_coin_hash, TALER_PQ_array_of_denom_hash, + TALER_PQ_array_of_hash_code, /** * Amounts *without* currency. */ diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c index 4764f7d1c..d8655db08 100644 --- a/src/pq/pq_query_helper.c +++ b/src/pq/pq_query_helper.c @@ -846,14 +846,14 @@ qconv_array ( same_sized = (0 != meta->same_size); #define RETURN_UNLESS(cond) \ - do { \ - if (! (cond)) \ - { \ - GNUNET_break ((cond)); \ - noerror = false; \ - goto DONE; \ - } \ - } while (0) + do { \ + if (! (cond)) \ + { \ + GNUNET_break ((cond)); \ + noerror = false; \ + goto DONE; \ + } \ + } while (0) /* Calculate sizes and check bounds */ { @@ -1037,6 +1037,15 @@ qconv_array ( sizeof(struct TALER_DenominationHashP)); break; } + case TALER_PQ_array_of_hash_code: + { + const struct GNUNET_HashCode *hashes = data; + + GNUNET_memcpy (out, + &hashes[i], + sizeof(struct GNUNET_HashCode)); + break; + } default: { GNUNET_assert (0); @@ -1171,6 +1180,26 @@ TALER_PQ_query_param_array_denom_hash ( struct GNUNET_PQ_QueryParam +TALER_PQ_query_param_array_hash_code ( + size_t num, + const struct GNUNET_HashCode *hashes, + struct GNUNET_PQ_Context *db) +{ + Oid oid; + GNUNET_assert (GNUNET_OK == + GNUNET_PQ_get_oid_by_name (db, "gnunet_hashcode", &oid)); + return query_param_array_generic (num, + true, + hashes, + NULL, + sizeof(struct GNUNET_HashCode), + TALER_PQ_array_of_hash_code, + oid, + NULL); +} + + +struct GNUNET_PQ_QueryParam TALER_PQ_query_param_array_amount ( size_t num, const struct TALER_Amount *amounts, diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c index 9acf80716..915aad144 100644 --- a/src/pq/pq_result_helper.c +++ b/src/pq/pq_result_helper.c @@ -1208,7 +1208,7 @@ extract_array_generic ( in += sizeof(val); /* total size for this array-entry */ - FAIL_IF (sizeof(ap) > sz); + FAIL_IF (sizeof(ap) != sz); GNUNET_memcpy (&ap, in, @@ -1249,6 +1249,30 @@ extract_array_generic ( } return GNUNET_OK; + case TALER_PQ_array_of_hash_code: + if (NULL != dst_size) + *dst_size = sizeof(struct GNUNET_HashCode) * (header.dim); + out = GNUNET_new_array (header.dim, + struct GNUNET_HashCode); + *((void **) dst) = out; + for (uint32_t i = 0; i < header.dim; i++) + { + uint32_t val; + size_t sz; + + GNUNET_memcpy (&val, + in, + sizeof(val)); + sz = ntohl (val); + FAIL_IF (sz != sizeof(struct GNUNET_HashCode)); + in += sizeof(uint32_t); + *(struct GNUNET_HashCode *) out = + *(struct GNUNET_HashCode *) in; + in += sz; + out += sz; + } + return GNUNET_OK; + case TALER_PQ_array_of_blinded_coin_hash: if (NULL != dst_size) *dst_size = sizeof(struct TALER_BlindedCoinHashP) * (header.dim); @@ -1504,4 +1528,34 @@ TALER_PQ_result_spec_array_amount ( } +struct GNUNET_PQ_ResultSpec +TALER_PQ_result_spec_array_hash_code ( + struct GNUNET_PQ_Context *db, + const char *name, + size_t *num, + struct GNUNET_HashCode **hashes) +{ + struct ArrayResultCls *info = GNUNET_new (struct ArrayResultCls); + + info->num = num; + info->typ = TALER_PQ_array_of_hash_code; + info->db = db; + GNUNET_assert (GNUNET_OK == + GNUNET_PQ_get_oid_by_name (db, + "gnunet_hashcode", + &info->oid)); + + struct GNUNET_PQ_ResultSpec res = { + .conv = extract_array_generic, + .cleaner = array_cleanup, + .dst = (void *) hashes, + .fname = name, + .cls = info, + }; + return res; + + +} + + /* end of pq_result_helper.c */ diff --git a/src/pq/test_pq.c b/src/pq/test_pq.c index 237c8a9ef..0fd2bfddf 100644 --- a/src/pq/test_pq.c +++ b/src/pq/test_pq.c @@ -21,6 +21,7 @@ #include "platform.h" #include "taler_util.h" #include "taler_pq_lib.h" +#include <gnunet/gnunet_pq_lib.h> /** @@ -39,14 +40,18 @@ postgres_prepare (struct GNUNET_PQ_Context *db) ",json" ",aamount" ",tamountc" + ",hash" + ",hashes" ") VALUES " - "($1, $2, $3, $4);"), + "($1, $2, $3, $4, $5, $6);"), GNUNET_PQ_make_prepare ("test_select", "SELECT" " tamount" ",json" ",aamount" ",tamountc" + ",hash" + ",hashes" " FROM test_pq;"), GNUNET_PQ_PREPARED_STATEMENT_END }; @@ -67,6 +72,20 @@ run_queries (struct GNUNET_PQ_Context *conn) struct TALER_Amount tamount; struct TALER_Amount aamount[3]; struct TALER_Amount tamountc; + struct GNUNET_HashCode hc = + {{0xdeadbeef,0xdeadbeef,0xdeadbeef,0xdeadbeef, + 0xdeadbeef,0xdeadbeef,0xdeadbeef,0xdeadbeef, + 0xdeadbeef,0xdeadbeef,0xdeadbeef,0xdeadbeef, + 0xdeadbeef,0xdeadbeef,0xdeadbeef,0xdeadbeef, }}; + struct GNUNET_HashCode hcs[2] = + {{{0xc0feec0f,0xc0feec0f,0xc0feec0f,0xc0feec0f, + 0xc0feec0f,0xc0feec0f,0xc0feec0f,0xc0feec0f, + 0xc0feec0f,0xc0feec0f,0xc0feec0f,0xc0feec0f, + 0xc0feec0f,0xc0feec0f,0xc0feec0f,0xc0feec0f,}}, + {{0xdeadbeaf,0xdeadbeaf,0xdeadbeaf,0xdeadbeaf, + 0xdeadbeaf,0xdeadbeaf,0xdeadbeaf,0xdeadbeaf, + 0xdeadbeaf,0xdeadbeaf,0xdeadbeaf,0xdeadbeaf, + 0xdeadbeaf,0xdeadbeaf,0xdeadbeaf,0xdeadbeaf,}}}; json_t *json; GNUNET_assert (GNUNET_OK == @@ -100,6 +119,11 @@ run_queries (struct GNUNET_PQ_Context *conn) conn), TALER_PQ_query_param_amount_with_currency (conn, &tamountc), + GNUNET_PQ_query_param_fixed_size (&hc, + sizeof (hc)), + TALER_PQ_query_param_array_hash_code (2, + hcs, + conn), GNUNET_PQ_query_param_end }; PGresult *result; @@ -122,7 +146,10 @@ run_queries (struct GNUNET_PQ_Context *conn) struct TALER_Amount tamount2; struct TALER_Amount tamountc2; struct TALER_Amount *pamount; + struct GNUNET_HashCode hc2; + struct GNUNET_HashCode *hcs2; size_t npamount; + size_t nhcs; json_t *json2; struct GNUNET_PQ_QueryParam params_select[] = { GNUNET_PQ_query_param_end @@ -140,6 +167,12 @@ run_queries (struct GNUNET_PQ_Context *conn) &pamount), TALER_PQ_result_spec_amount_with_currency ("tamountc", &tamountc2), + GNUNET_PQ_result_spec_auto_from_type ("hash", + &hc2), + TALER_PQ_result_spec_array_hash_code (conn, + "hashes", + &nhcs, + &hcs2), GNUNET_PQ_result_spec_end }; @@ -168,6 +201,13 @@ run_queries (struct GNUNET_PQ_Context *conn) GNUNET_break (0 == TALER_amount_cmp (&tamountc, &tamountc2)); + GNUNET_break (0 == GNUNET_memcmp (&hc,&hc2)); + for (size_t i = 0; i < 2; i++) + { + GNUNET_break (0 == + GNUNET_memcmp (&hcs[i], + &hcs2[i])); + } GNUNET_PQ_cleanup_result (results_select); } return 0; @@ -181,6 +221,14 @@ main (int argc, struct GNUNET_PQ_ExecuteStatement es[] = { GNUNET_PQ_make_execute ("DO $$ " " BEGIN" + " CREATE DOMAIN gnunet_hashcode AS BYTEA" + " CHECK(length(VALUE)=64);" + " EXCEPTION" + " WHEN duplicate_object THEN null;" + " END " + "$$;"), + GNUNET_PQ_make_execute ("DO $$ " + " BEGIN" " CREATE TYPE taler_amount AS" " (val INT8, frac INT4);" " EXCEPTION" @@ -200,6 +248,8 @@ main (int argc, ",json VARCHAR NOT NULL" ",aamount taler_amount[]" ",tamountc taler_amount_currency" + ",hash gnunet_hashcode" + ",hashes gnunet_hashcode[]" ")"), GNUNET_PQ_EXECUTE_STATEMENT_END }; diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am index 18fe2a49b..6a07c933d 100644 --- a/src/testing/Makefile.am +++ b/src/testing/Makefile.am @@ -561,7 +561,7 @@ EXTRA_DIST = \ test_bank_api_nexus.conf \ test_exchange_api_home/taler/auditor/offline-keys/auditor.priv \ test_exchange_api_home/.local/share/taler/exchange-offline/master.priv \ - test_exchange_api_keys_cherry_picking_home/taler/exchange-offline/master.priv \ + test_exchange_api_home/.local/share/taler/auditor/offline-keys/auditor.priv \ test_exchange_api.conf \ test_exchange_api-cs.conf \ test_exchange_api-rsa.conf \ diff --git a/src/testing/test_exchange_api.c b/src/testing/test_exchange_api.c index 4ae47aff2..caeec1e76 100644 --- a/src/testing/test_exchange_api.c +++ b/src/testing/test_exchange_api.c @@ -55,7 +55,7 @@ static struct TALER_TESTING_Credentials cred; /** * Some tests behave differently when using CS as we cannot - * re-use the coin private key for different denominations + * reuse the coin private key for different denominations * due to the derivation of it with the /csr values. Hence * some tests behave differently in CS mode, hence this * flag. diff --git a/src/testing/test_exchange_api_age_restriction.c b/src/testing/test_exchange_api_age_restriction.c index 90d35ebc3..5ba24a00c 100644 --- a/src/testing/test_exchange_api_age_restriction.c +++ b/src/testing/test_exchange_api_age_restriction.c @@ -47,7 +47,7 @@ static struct TALER_TESTING_Credentials cred; /** * Some tests behave differently when using CS as we cannot - * re-use the coin private key for different denominations + * reuse the coin private key for different denominations * due to the derivation of it with the /csr values. Hence * some tests behave differently in CS mode, hence this * flag. diff --git a/src/testing/test_exchange_p2p.c b/src/testing/test_exchange_p2p.c index 1c075fc1b..0c4fb48ec 100644 --- a/src/testing/test_exchange_p2p.c +++ b/src/testing/test_exchange_p2p.c @@ -48,7 +48,7 @@ struct TALER_TESTING_Credentials cred; /** * Some tests behave differently when using CS as we cannot - * re-use the coin private key for different denominations + * reuse the coin private key for different denominations * due to the derivation of it with the /csr values. Hence * some tests behave differently in CS mode, hence this * flag. diff --git a/src/testing/testing_api_cmd_batch_withdraw.c b/src/testing/testing_api_cmd_batch_withdraw.c index e4c054c5f..75311e7dc 100644 --- a/src/testing/testing_api_cmd_batch_withdraw.c +++ b/src/testing/testing_api_cmd_batch_withdraw.c @@ -85,7 +85,7 @@ struct CoinState /** * If age > 0, put here the corresponding age commitment with its proof and - * its hash, respectivelly. + * its hash, respectively. */ struct TALER_AgeCommitmentProof age_commitment_proof; struct TALER_AgeCommitmentHash h_age_commitment; diff --git a/src/testing/testing_api_cmd_withdraw.c b/src/testing/testing_api_cmd_withdraw.c index 13162a34a..a98e69521 100644 --- a/src/testing/testing_api_cmd_withdraw.c +++ b/src/testing/testing_api_cmd_withdraw.c @@ -62,7 +62,7 @@ struct WithdrawState /** * Reference to a withdraw or reveal operation from which we should - * re-use the private coin key, or NULL for regular withdrawal. + * reuse the private coin key, or NULL for regular withdrawal. */ const char *reuse_coin_key_ref; @@ -144,7 +144,7 @@ struct WithdrawState /** * If age > 0, put here the corresponding age commitment with its proof and - * its hash, respectivelly. + * its hash, respectively. */ struct TALER_AgeCommitmentProof age_commitment_proof; struct TALER_AgeCommitmentHash h_age_commitment; diff --git a/src/util/age_restriction.c b/src/util/age_restriction.c index f79c767a9..c2a7fc07c 100644 --- a/src/util/age_restriction.c +++ b/src/util/age_restriction.c @@ -681,7 +681,7 @@ TALER_age_restriction_from_secret ( /* Create as many private keys as allow with max_age and derive the * corresponding public keys. The rest of the needed public keys are created - * by scalar mulitplication with the TALER_age_commitment_base_public_key. */ + * by scalar multiplication with the TALER_age_commitment_base_public_key. */ for (size_t i = 0; i < num_pub; i++) { enum GNUNET_GenericReturnValue ret; diff --git a/src/util/currencies.conf b/src/util/currencies.conf index 5f4fcbe60..0fa831bf3 100644 --- a/src/util/currencies.conf +++ b/src/util/currencies.conf @@ -78,3 +78,12 @@ fractional_input_digits = 0 fractional_normal_digits = 0 fractional_trailing_zero_digits = 0 alt_unit_names = {"0":"WAI","3":"KWAI","6":"MWAI","9":"GWAI","12":"Szabo","15":"Finney","18":"Ether","21":"KEther","24":"MEther"} + +[currency-netzbon] +ENABLED=YES +name=NetzBon +code=NETZBON +fractional_input_digits=2 +fractional_normal_digits=2 +fractional_trailing_zero_digits=2 +alt_unit_names = {"0":"NETZBON"} |