aboutsummaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/include')
-rw-r--r--src/include/taler_exchangedb_plugin.h117
-rw-r--r--src/include/taler_extensions.h201
-rw-r--r--src/include/taler_extensions_policy.h199
3 files changed, 294 insertions, 223 deletions
diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h
index 80a19b67..881e0cef 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -26,6 +26,7 @@
#include <gnunet/gnunet_db_lib.h>
#include "taler_json_lib.h"
#include "taler_signatures.h"
+#include "taler_extensions_policy.h"
/**
@@ -223,7 +224,6 @@ enum TALER_EXCHANGEDB_ReplicatedTable
TALER_EXCHANGEDB_RT_EXTENSIONS,
TALER_EXCHANGEDB_RT_POLICY_DETAILS,
TALER_EXCHANGEDB_RT_POLICY_FULFILMENTS,
- TALER_EXCHANGEDB_RT_POLICY_DETAILS_FULFILMENTS,
TALER_EXCHANGEDB_RT_PURSE_REQUESTS,
TALER_EXCHANGEDB_RT_PURSE_REFUNDS,
TALER_EXCHANGEDB_RT_PURSE_MERGES,
@@ -528,24 +528,27 @@ struct TALER_EXCHANGEDB_TableData
struct
{
- char *policy_options;
- struct GNUNET_HashCode serial_id;
+ struct GNUNET_HashCode hash_code;
+ json_t *policy_json;
+ bool no_policy_json;
struct GNUNET_TIME_Timestamp deadline;
- uint16_t timeout_fulfilment_state;
- uint16_t fulfilment_state;
+ struct TALER_Amount commitment;
+ struct TALER_Amount accumulated_total;
+ struct TALER_Amount fee;
+ struct TALER_Amount transferable;
+ uint16_t fulfillment_state; /* will also be recomputed */
+ uint64_t fulfillment_id;
+ bool no_fulfillment_id;
} policy_details;
struct
{
- struct GNUNET_HashCode serial_id;
- uint64_t fulfilment_id;
- } policy_details_fulfilments;
-
- struct
- {
- char *fulfilment_proof;
- struct GNUNET_TIME_Timestamp fulfilment_timestamp;
- } policy_fulfilments;
+ struct GNUNET_TIME_Timestamp fulfillment_timestamp;
+ char *fulfillment_proof;
+ struct GNUNET_HashCode h_fulfillment_proof;
+ struct GNUNET_HashCode *policy_hash_codes;
+ size_t policy_hash_codes_count;
+ } policy_fulfillments;
struct
{
@@ -889,7 +892,6 @@ struct TALER_EXCHANGEDB_DenominationKeyMetaData
struct TALER_AgeMask age_mask;
};
-
/**
* Signature of a function called with information about the exchange's
* denomination keys.
@@ -1446,36 +1448,28 @@ struct TALER_EXCHANGEDB_Deposit
char *receiver_wire_account;
/**
- * Additional details for a policy relevant for this
- * deposit operation, possibly NULL!
+ * Additional policy and its options, relevant for this deposit operation,
+ * possibly NULL!
*/
- json_t *policy_details;
- bool has_policy_details;
+ json_t *policy_json;
- /**
- * If policy_details are present, the corresponding policy extension
- * calculates a serial id under which the policy_details shall be stored in
- * the policy_details table.
+ /*
+ * True if @e policy_json was provided
*/
- struct GNUNET_HashCode policy_serial_id;
+ bool has_policy;
/**
- * If policy_details are present, the corresponding policy extension can set
- * a deadline for this policy. Can be "forever".
+ * Hash over the @e policy_options. Only filled if @e has_policy is true.
+ * Needed for the verification of the deposit's signature
*/
- struct GNUNET_TIME_Timestamp policy_deadline;
-
- /**
- * The state that a _pending_ policy should be put into once the timeout triggers
- */
- uint16_t policy_state_on_timeout;
-
+ struct TALER_ExtensionPolicyHashP h_policy;
/**
- * Hash over the @e policy_details. Only filled if has_policy_details is
- * true.
+ * If @e policy_json was present, the corresponding policy extension
+ * calculates these details. These will be persisted in the policy_details
+ * table.
*/
- struct TALER_ExtensionPolicyHashP h_policy;
+ struct TALER_PolicyDetails policy_details;
/**
* Time when this request was generated. Used, for example, to
@@ -1549,8 +1543,8 @@ struct TALER_EXCHANGEDB_DepositListEntry
struct TALER_PrivateContractHashP h_contract_terms;
/**
- * Hash over the poliy data for this deposit
- * (remains unknown to the Exchange).
+ * Hash over the policy data for this deposit (remains unknown to the
+ * Exchange). Needed for the verification of the deposit's signature
*/
struct TALER_ExtensionPolicyHashP h_policy;
@@ -3342,6 +3336,39 @@ struct TALER_EXCHANGEDB_Plugin
bool *conflict,
bool *nonce_reuse);
+ /**
+ * Retrieve the details to a policy given by its hash_code
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @param hc Hash code that identifies the policy
+ * @param[out] detail retrieved policy details
+ * @return query execution status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*get_policy_details)(
+ void *cls,
+ const struct GNUNET_HashCode *hc,
+ struct TALER_PolicyDetails *detail);
+
+ /**
+ * Persist the policy details that extends a deposit. The particular policy
+ * - referenced by details->hash_code - might already exist in the table, in
+ * which case the call will update the contents of the record with @e details
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @param details The parsed `struct TALER_PolicyDetails` according to the responsible policy extension.
+ * @param[out] policy_details_serial_id The ID of the entry in the policy_details table
+ * @param[out] accumulated_total The total amount accumulated in that policy
+ * @param[out] fulfillment_state The state of policy. If the state was Insufficient prior to the call and the provided deposit raises the accumulated_total above the commitment, it will be set to Ready.
+ * @return query execution status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*persist_policy_details)(
+ void *cls,
+ const struct TALER_PolicyDetails *details,
+ uint64_t *policy_details_serial_id,
+ struct TALER_Amount *accumulated_total,
+ enum TALER_PolicyFulfillmentState *fulfillment_state);
/**
* Perform deposit operation, checking for sufficient balance
@@ -3351,6 +3378,7 @@ struct TALER_EXCHANGEDB_Plugin
* @param deposit deposit operation details
* @param known_coin_id row of the coin in the known_coins table
* @param h_payto hash of the merchant's payto URI
+ * @param policy_details_serial_id (pointer to) the row ID of the policy details, maybe NULL
* @param[in,out] exchange_timestamp time to use for the deposit (possibly updated)
* @param[out] balance_ok set to true if the balance was sufficient
* @param[out] in_conflict set to true if the deposit conflicted
@@ -3362,6 +3390,7 @@ struct TALER_EXCHANGEDB_Plugin
const struct TALER_EXCHANGEDB_Deposit *deposit,
uint64_t known_coin_id,
const struct TALER_PaytoHashP *h_payto,
+ uint64_t *policy_details_serial_id,
struct GNUNET_TIME_Timestamp *exchange_timestamp,
bool *balance_ok,
bool *in_conflict);
@@ -3389,6 +3418,18 @@ struct TALER_EXCHANGEDB_Plugin
bool *zombie_required,
bool *balance_ok);
+ /**
+ * Add a proof of fulfillment of an policy
+ *
+ * @param cls the plugin-specific state
+ * @param[in,out] fulfillment The proof of fulfillment and serial_ids of the policy_details along with their new state and potential new amounts.
+ * @return query execution status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*add_policy_fulfillment_proof)(
+ void *cls,
+ struct TALER_PolicyFulfillmentTransactionData *fulfillment);
+
/**
* Check if the given @a nonce was properly locked to the given @a old_coin_pub. If so, check if we already
diff --git a/src/include/taler_extensions.h b/src/include/taler_extensions.h
index 5a5841e5..24e0366d 100644
--- a/src/include/taler_extensions.h
+++ b/src/include/taler_extensions.h
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014-2021 Taler Systems SA
+ Copyright (C) 2022 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
@@ -25,7 +25,7 @@
#include "taler_crypto_lib.h"
#include "taler_json_lib.h"
#include "taler_mhd_lib.h"
-#include "taler_exchangedb_plugin.h"
+#include "taler_extensions_policy.h"
#define TALER_EXTENSION_SECTION_PREFIX "exchange-extension-"
@@ -54,8 +54,8 @@ struct TALER_Extensions
};
/* Forward declarations */
-enum TALER_PolicyFulfilmentState;
-struct TALER_PolicyFulfilmentOutcome;
+enum TALER_PolicyFulfillmentState;
+struct TALER_PolicyFulfillmentOutcome;
/*
* @brief Represents the implementation of an extension.
@@ -165,31 +165,23 @@ struct TALER_Extension
*/
/**
- * @brief Handler to check a policy. Can be NULL;
+ * @brief Handler to check an incoming policy and create a
+ * TALER_PolicyDetails. Can be NULL;
*
* When a deposit request refers to this extension in its policy
* (see https://docs.taler.net/core/api-exchange.html#deposit), this handler
* will be called before the deposit transaction.
*
- * @param[in] policy_details Details about the policy, provided by the client
+ * @param[in] policy_json Details about the policy, provided by the client
* during a deposit request.
- * @param[out] serial On success, will contain the serial-ID under which the
- * exchange should save the policy_details in the deposit table.
- * @param[out] deadline On success, set to the deadline until the policy must
- * be fulfilled. Might be "forever". This value is used by an
- * external mechanism to detect timeouts.
- * @param[out] state_on_timeout On GNUNET_OK, which state shall the
- * fulfilment of this policy be put in. MUST be either
- * TALER_PolicyFulfilmentTimeoutTransfer or
- * TALER_PolicyFulfilmentTimeoutRefreshable
+ * @param[out] details On success, will contain the details to the policy,
+ * evaluated by the corresponding policy handler.
* @param[out] error_hint On error, will contain a hint
* @return GNUNET_OK if the data was accepted by the extension.
*/
- enum GNUNET_GenericReturnValue (*parse_policy_details)(
- const json_t *policy_details,
- struct GNUNET_HashCode *serial,
- struct GNUNET_TIME_Timestamp *deadline,
- enum TALER_PolicyFulfilmentState *state_on_timeout,
+ enum GNUNET_GenericReturnValue (*create_policy_details)(
+ const json_t *policy_json,
+ struct TALER_PolicyDetails *details,
const char **error_hint);
/**
@@ -197,18 +189,16 @@ struct TALER_Extension
*
* @param[in] root The JSON body from the request
* @param[in] args Additional query parameters of the request.
- * @param[in] serial_id_check Helper function to check the presence of serial_ids in policy_details. Can be used by the handler to ensure the presence of entries before starting calculations.
- * @param[out] outcome Result of the operation. Must be freed via TALER_policy_fulfilment_outcome_free after use.
+ * @param[in,out] details List of policy details related to the incoming fulfillment proof
+ * @param[in] details_len Size of the list @e details
* @param[out] output JSON output to return to the client
* @return GNUNET_OK on success.
*/
enum GNUNET_GenericReturnValue (*policy_post_handler)(
const json_t *root,
const char *const args[],
- enum GNUNET_GenericReturnValue (*serial_id_check)(struct GNUNET_HashCode
- serial_ids[], size_t
- size),
- struct TALER_PolicyFulfilmentOutcome **outcome,
+ struct TALER_PolicyDetails *details,
+ size_t details_len,
json_t **output);
/**
@@ -395,163 +385,4 @@ TALER_extensions_is_age_restriction_enabled ();
struct TALER_AgeMask
TALER_extensions_get_age_restriction_mask ();
-
-/*
- * ===================================
- * Policy extensions related API
- * ===================================
- */
-
-
-/*
- * @brief Describes the states of fulfilment of a policy bound to a deposit
- */
-enum TALER_PolicyFulfilmentState
-{
- /* Initial state of the policy */
- TALER_PolicyFulfilmentPending = 0,
-
- /*
- * Policy provably fulfilled. The semantics of the policy require that
- * the exchange MUST transfer amount in the associated deposit to the
- * payto-URI */
- TALER_PolicyFulfilmentSuccessTransfer = 1,
-
- /*
- * Policy provably fulfilled. The semantics of the policy require that
- * the coins' value in the associated deposit remains and the owner can
- * refresh them. */
- TALER_PolicyFulfilmentSuccessRefreshable = 2,
-
- /*
- * Policy provably UNfulfilled. The semantics of the policy require
- * that the exchange MUST transfer amount in the associated deposit to
- * the payto-URI. */
- TALER_PolicyFulfilmentFailureTransfer = 3,
-
- /*
- * Policy provably UNfulfilled. The semantics of the policy require that
- * the coins' value in the associated deposit remains and the owner can
- * refresh them. */
- TALER_PolicyFulfilmentFailureRefreshable = 4,
-
- /*
- * Policy timed out. The semantics of the policy require that the
- * exchange MUST transfer amount in the associated deposit to the
- * payto-URI. */
- TALER_PolicyFulfilmentTimeoutTransfer = 5,
-
- /*
- * Policy timed out. The semantics of the policy require that the
- * coins' value in the associated deposit remains and the owner can
- * refresh them. */
- TALER_PolicyFulfilmentTimeoutRefreshable = 6,
-
- TALER_PolicyFulfilmentStateMax = TALER_PolicyFulfilmentTimeoutRefreshable
-};
-
-
-const char *
-TALER_policy_fulfilment_state_str (enum TALER_PolicyFulfilmentState state);
-
-/*
- * @brief Respresents the outcome of a policy fulfilment evaluation
- * returned by a http_post_handler.
- */
-struct TALER_PolicyFulfilmentOutcome
-{
- size_t len;
- struct TALER_PolicyFulfilmentOutcomePosition
- {
- /* Identifies the particular policy in the policy_details */
- struct GNUNET_HashCode serial_id;
-
- /* The state that the policy should be be put into. */
- enum TALER_PolicyFulfilmentState state;
-
- /* If @e has_new_amount is true, the actual amount to be transfered
- * according to the @e state is not taken from the associated deposit
- * entry, but provided with @new_amount
- */
- bool has_new_amount;
- struct TALER_Amount new_amount;
-
- } *positions;
-};
-
-
-/*
- * @brief allocate a TALER_PolicyFulfilmentOutcome
- */
-struct TALER_PolicyFulfilmentOutcome *
-TALER_policy_fulfilment_outcome_new (size_t len);
-
-/*
- * @brief free the content of a TALER_PolicyFulfilmentOutcome
- */
-void
-TALER_policy_fulfilment_outcome_free (
- struct TALER_PolicyFulfilmentOutcome *outcome);
-
-
-/*
- * @brief Extracts meta information from policy_details
- *
- * @param[in] policy_details JSON of the policy detail from a deposit request
- * @param[out] serial On GNUNET_OK, the hash code that should be used to save the policy_details in the policy_details table
- * @param[out] deadline On GNUNET_OK, the deadline that should be saved in the policy_details table
- * @param[out] state_on_timeout On GNUNET_OK, which state shall the fulfilment of this policy be put in
- * @param[out] error_hint On GNUNET_SYSERR, will contain a hint for the reason why it failed
- * @return GNUNET_OK on success, with *extension set to the correct extension.
- * GNUNET_NO, when no extension was found. GNUNET_SYSERR when the JSON was
- * invalid, with *error_hint maybe non-NULL.
- */
-enum GNUNET_GenericReturnValue
-TALER_extensions_extract_meta_data_from_policy_details (
- const json_t *policy_details,
- struct GNUNET_HashCode *serial,
- struct GNUNET_TIME_Timestamp *deadline,
- enum TALER_PolicyFulfilmentState *state_on_timeout,
- const char **error_hint);
-
-
-/*
- * ================================
- * Merchant refund policy
- * ================================
- */
-struct TALER_ExtensionPolicyMerchantRefundPolicyConfig
-{
- struct GNUNET_TIME_Relative max_timeout;
-};
-
-/*
- * ================================
- * Brandt-Vickrey Auctions policy
- * ================================
- */
-/*
- * @brief Configuration for Brandt-Vickrey auctions policy
- */
-struct TALER_ExtensionPolicyBrandtVickreyAuctionConfig
-{
- uint16_t max_bidders;
- uint16_t max_prices;
- struct TALER_Amount auction_fee;
-};
-
-
-/*
- * ================================
- * Escrowed Payments policy
- * ================================
- */
-/*
- * @brief Configuration for escrowed payments policy
- */
-struct TALER_ExtensionPolicyEscrowedPaymentsConfig
-{
- struct GNUNET_TIME_Relative max_timeout;
-};
-
#endif
diff --git a/src/include/taler_extensions_policy.h b/src/include/taler_extensions_policy.h
new file mode 100644
index 00000000..cd75f2d4
--- /dev/null
+++ b/src/include/taler_extensions_policy.h
@@ -0,0 +1,199 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file include/taler_extensions_policy.h
+ * @brief Interface for policy extensions
+ * @author Özgür Kesim
+ */
+#ifndef TALER_EXTENSIONS_POLICY_H
+#define TALER_EXTENSIONS_POLICY_H
+
+#include <gnunet/gnunet_util_lib.h>
+#include "taler_crypto_lib.h"
+#include "taler_json_lib.h"
+#include "taler_mhd_lib.h"
+
+/*
+ * @brief Describes the states of fulfillment of a policy bound to a deposit
+ */
+enum TALER_PolicyFulfillmentState
+{
+ /* General error state of an fulfillment. */
+ TALER_PolicyFulfillmentFailure = 0,
+
+ /* The policy is not yet ready due to insufficient funding. More deposits are
+ * necessary for it to become ready . */
+ TALER_PolicyFulfillmentInsufficient = 1,
+
+ /* The policy is funded and ready, pending */
+ TALER_PolicyFulfillmentReady = 2,
+
+ /* Policy is provably fulfilled. */
+ TALER_PolicyFulfillmentSuccess = 3,
+
+ /* Policy fulfillment has timed out */
+ TALER_PolicyFulfillmentTimeout = 4,
+
+ TALER_PolicyFulfillmentStateCount = TALER_PolicyFulfillmentTimeout + 1
+};
+
+
+/*
+ * @brief Returns a string representation of the state of a policy fulfillment
+ */
+const char *
+TALER_policy_fulfillment_state_str (enum TALER_PolicyFulfillmentState state);
+
+
+/* @brief Details of a policy for a deposit request */
+struct TALER_PolicyDetails
+{
+ /* Hash code that should be used for the .policy_hash_code field when
+ * this policy is saved in the policy_details table. */
+ struct GNUNET_HashCode hash_code;
+
+ /* Content of the policy in its original JSON form */
+ const json_t *policy_json;
+
+ /* When the deadline is meat 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
+ * amount_refreshable will be refreshable by the owner of the
+ * associated deposits's coins */
+ struct GNUNET_TIME_Timestamp deadline;
+
+ /* The amount to which this policy commits to. It must be at least as
+ * large as @e policy_fee. */
+ struct TALER_Amount commitment;
+
+ /* The total sum of contributions from coins so far to fund this
+ * policy. It must be at least as large as @commitment in order to be
+ * sufficiently funded. */
+ struct TALER_Amount accumulated_total;
+
+ /* The fee from the exchange for handling the policy. It is due when
+ * the state changes to Timeout or Success. */
+ struct TALER_Amount policy_fee;
+
+ /* The amount that will be transfered to the payto-URIs from the
+ * corresponding deposits when the fulfillment state changes to Timeout
+ * or Success. Note that a fulfillment handler can alter this upon
+ * arrival of a proof of fulfillment. The remaining amount
+ * (accumulated_amount - policy_amount - transferable_amount) */
+ struct TALER_Amount transferable_amount;
+
+ /* The state of fulfillment of a policy.
+ * - If the state is Insufficient, the client is required to call
+ * /deposit -maybe multiple times- with enough coins and the same
+ * policy details in order to reach the required amount. The state is
+ * then changed to Ready.
+ * - If the state changes to Timeout or Success, a handler will transfer
+ * the amount (total_amount - policy_fee - refreshable_amount) to the
+ * payto-URI from the corresponding deposit. The value
+ * amount_refreshable will be refreshable by the owner of the
+ * associated deposits's coins. */
+ enum TALER_PolicyFulfillmentState fulfillment_state;
+
+ /* If there is a proof of fulfillment, the row ID from the
+ * policy_fulfillment table */
+ uint64_t policy_fulfillment_id;
+ bool no_policy_fulfillment_id;
+};
+
+/*
+ * @brief All information required for the database transaction when handling a
+ * proof of fulfillment request.
+ */
+struct TALER_PolicyFulfillmentTransactionData
+{
+ /* The incoming proof, provided by a client */
+ const json_t *proof;
+
+ /* The Hash of the proof */
+ struct GNUNET_HashCode h_proof;
+
+ /* The timestamp of retrieval of the proof */
+ struct GNUNET_TIME_Timestamp timestamp;
+
+ /* The ID of the proof in the policy_fulfillment table. Will be set
+ * during the transaction. Needed to fill the table
+ * policy_details_fulfillments. */
+ uint64_t fulfillment_id;
+
+ /* The list of policy details. Will be updated by the policy handler */
+ struct TALER_PolicyDetails *details;
+ size_t details_count;
+};
+
+
+
+/*
+ * @brief Extracts policy details from the deposit's policy options and the policy extensions
+ *
+ * @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
+ * @return GNUNET_OK on success, GNUNET_NO, when no extension was found. GNUNET_SYSERR when the JSON was
+ * invalid, with *error_hint maybe non-NULL.
+ */
+enum GNUNET_GenericReturnValue
+TALER_extensions_create_policy_details (
+ const json_t *policy_options,
+ struct TALER_PolicyDetails *details,
+ const char **error_hint);
+
+
+/*
+ * ================================
+ * Merchant refund policy
+ * ================================
+ */
+struct TALER_ExtensionPolicyMerchantRefundPolicyConfig
+{
+ struct GNUNET_TIME_Relative max_timeout;
+};
+
+/*
+ * ================================
+ * Brandt-Vickrey Auctions policy
+ * ================================
+ */
+/*
+ * @brief Configuration for Brandt-Vickrey auctions policy
+ */
+struct TALER_ExtensionPolicyBrandtVickreyAuctionConfig
+{
+ uint16_t max_bidders;
+ uint16_t max_prices;
+ struct TALER_Amount auction_fee;
+};
+
+
+/*
+ * ================================
+ * Escrowed Payments policy
+ * ================================
+ */
+/*
+ * @brief Configuration for escrowed payments policy
+ */
+struct TALER_ExtensionPolicyEscrowedPaymentsConfig
+{
+ struct GNUNET_TIME_Relative max_timeout;
+};
+
+#endif