summaryrefslogtreecommitdiff
path: root/src/backenddb
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-05-23 11:05:58 +0200
committerChristian Grothoff <christian@grothoff.org>2020-05-23 11:05:58 +0200
commit5ee782667a2ceb3088a1da2076f6047dc5fb4eaf (patch)
tree9e3a01daafff4f07dad67c1489ac8639da12fef9 /src/backenddb
parent49157c0beaeae761cac5daa22d8734880ee726dd (diff)
downloadmerchant-5ee782667a2ceb3088a1da2076f6047dc5fb4eaf.tar.gz
merchant-5ee782667a2ceb3088a1da2076f6047dc5fb4eaf.tar.bz2
merchant-5ee782667a2ceb3088a1da2076f6047dc5fb4eaf.zip
DB prep work
Diffstat (limited to 'src/backenddb')
-rw-r--r--src/backenddb/plugin_merchantdb_postgres.c300
1 files changed, 299 insertions, 1 deletions
diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c
index df6207b3..4664240a 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -4202,6 +4202,296 @@ postgres_purge_reserve (void *cls,
}
+/**
+ * Authorize a tip over @a amount from reserve @a reserve_pub. Remember
+ * the authorization under @a tip_id for later, together with the
+ * @a justification.
+ *
+ * @param cls closure, typically a connection to the db
+ * @param instance_id which instance should generate the tip
+ * @param reserve_pub which reserve is debited, NULL to pick one in the DB
+ * @param amount how high is the tip (with fees)
+ * @param justification why was the tip approved
+ * @param next_url where to send the URL post tip pickup
+ * @param[out] tip_id set to the unique ID for the tip
+ * @param[out] expiration set to when the tip expires
+ * @return transaction status,
+ * #TALER_EC_TIP_AUTHORIZE_RESERVE_EXPIRED if the reserve is known but has expired
+ * #TALER_EC_TIP_AUTHORIZE_RESERVE_UNKNOWN if the reserve is not known
+ * #TALER_EC_TIP_AUTHORIZE_INSUFFICIENT_FUNDS if the reserve has insufficient funds left
+ * #TALER_EC_TIP_AUTHORIZE_DB_HARD_ERROR on hard DB errors
+ * #TALER_EC_TIP_AUTHORIZE_DB_SOFT_ERROR on soft DB errors (client should retry)
+ * #TALER_EC_NONE upon success
+ */
+static enum TALER_ErrorCode
+postgres_authorize_tip (void *cls,
+ const char *instance_id,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_Amount *amount,
+ const char *justification,
+ const char *next_url,
+ struct GNUNET_HashCode *tip_id,
+ struct GNUNET_TIME_Absolute *expiration)
+{
+ struct PostgresClosure *pg = cls;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_string (instance_id),
+ // FIXME: not so easy: reserve_pub MAY be NULL!
+ GNUNET_PQ_query_param_auto_from_type (reserve_pub),
+ TALER_PQ_query_param_amount (amount),
+ GNUNET_PQ_query_param_string (justification),
+ GNUNET_PQ_query_param_string (next_url),
+ GNUNET_PQ_query_param_auto_from_type (tip_id),
+ GNUNET_PQ_query_param_end
+ };
+ struct TALER_Amount tips_committed;
+ struct TALER_Amount exchange_initial_balance;
+
+ retries = 0;
+ check_connection (pg);
+RETRY:
+ if (MAX_RETRIES < ++retries)
+ return GNUNET_DB_STATUS_SOFT_ERROR; // FIXME: wrong EC!
+ if (GNUNET_OK !=
+ postgres_start (pg,
+ "enable tip reserve"))
+ {
+ GNUNET_break (0);
+ return GNUNET_DB_STATUS_HARD_ERROR; // FIXME: wrong EC!
+ }
+ if (NULL == reserve_pub)
+ {
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_string (instance_id),
+ TALER_PQ_query_param_amount (amount),
+ GNUNET_PQ_query_param_end
+ };
+ qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
+ "lookup_reserve",
+ params,
+ &lookup_accounts_cb,
+ lic);
+
+ }
+
+
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_absolute_time ("expiration",
+ &old_expiration),
+ TALER_PQ_RESULT_SPEC_AMOUNT ("tips_committed",
+ &tips_committed),
+ TALER_PQ_RESULT_SPEC_AMOUNT ("exchange_initial_balance",
+ &exchange_initial_balance),
+ GNUNET_PQ_result_spec_end
+ };
+
+
+ check_connection (pg);
+ return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "purge_reserve",
+ params);
+}
+
+
+/**
+ * Lookup pickup details for pickup @a pickup_id.
+ *
+ * @param cls closure, typically a connection to the db
+ * @param instance_id which instance should we lookup tip details for
+ * @param tip_id which tip should we lookup details on
+ * @param pickup_id which pickup should we lookup details on
+ * @param[out] exchange_url which exchange is the tip withdrawn from
+ * @param[out] reserve_priv private key the tip is withdrawn from (set if still available!)
+ * @param sigs_length length of the @a sigs array
+ * @param[out] sigs set to the (blind) signatures we have for this @a pickup_id,
+ * those that are unavailable are left at NULL
+ * @return transaction status
+ */
+static enum GNUNET_DB_QueryStatus
+postgres_lookup_pickup (void *cls,
+ const char *instance_id,
+ const struct GNUNET_HashCode *tip_id,
+ const struct GNUNET_HashCode *pickup_id,
+ char **exchange_url,
+ struct TALER_ReservePrivateKeyP *reserve_priv,
+ unsigned int sigs_length,
+ struct GNUNET_CRYPTO_RsaSignature *sigs[])
+{
+}
+
+
+/**
+* Lookup tip details for tip @a tip_id.
+*
+* @param cls closure, typically a connection to the db
+* @param instance_id which instance should we lookup tip details for
+* @param tip_id which tip should we lookup details on
+* @param[out] total_authorized amount how high is the tip (with fees)
+* @param[out] total_picked_up how much of the tip was so far picked up (with fees)
+* @param[out] expiration set to when the tip expires
+* @param[out] exchange_url set to the exchange URL where the reserve is
+* @param[out] reserve_priv set to private key of reserve to be debited
+* @return transaction status,
+* #TALER_EC_TIP_AUTHORIZE_RESERVE_EXPIRED if the reserve is known but has expired
+* #TALER_EC_TIP_AUTHORIZE_RESERVE_UNKNOWN if the reserve is not known
+* #TALER_EC_TIP_AUTHORIZE_INSUFFICIENT_FUNDS if the reserve has insufficient funds left
+* #TALER_EC_TIP_AUTHORIZE_DB_HARD_ERROR on hard DB errors
+* #TALER_EC_TIP_AUTHORIZE_DB_SOFT_ERROR on soft DB errors (client should retry)
+* #TALER_EC_NONE upon success
+*/
+static enum TALER_ErrorCode
+postgres_lookup_tip (void *cls,
+ const char *instance_id,
+ const struct GNUNET_HashCode *tip_id,
+ struct TALER_Amount *total_authorized,
+ struct TALER_Amount *total_picked_up,
+ struct GNUNET_TIME_Absolute *expiration,
+ char **exchange_url,
+ struct TALER_ReservePrivateKeyP *reserve_priv)
+{
+ struct PostgresClosure *pg = cls;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_string (instance_id),
+ GNUNET_PQ_query_param_auto_from_type (tip_id),
+ GNUNET_PQ_query_param_end
+ };
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ TALER_PQ_RESULT_SPEC_AMOUNT ("total_authorized",
+ total_authorized),
+ TALER_PQ_RESULT_SPEC_AMOUNT ("total_picked_up",
+ total_picked_up),
+ GNUNET_PQ_result_spec_absolute_time ("expiration",
+ expiration),
+ GNUNET_PQ_result_spec_string ("exchange_url",
+ exchange_url),
+ GNUNET_PQ_result_spec_fixed_auto ("reserve_priv",
+ reserve_priv),
+ GNUNET_PQ_result_spec_end
+ };
+
+ check_connection (pg);
+ return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "lookup_tip", // FIXME: write SQL!
+ params,
+ rs);
+}
+
+
+/**
+ * Lookup tip details for tip @a tip_id.
+ *
+ * @param cls closure, typically a connection to the db
+ * @param instance_id which instance should we lookup tip details for
+ * @param tip_id which tip should we lookup details on
+ * @param fpu should we fetch details about individual pickups
+ * @param[out] total_authorized amount how high is the tip (with fees)
+ * @param[out] total_picked_up how much of the tip was so far picked up (with fees)
+ * @param[out] justification why was the tip approved
+ * @param[out] expiration set to when the tip expires
+ * @param[out] reserve_pub set to which reserve is debited
+ * @param[out] pickups_length set to the length of @e pickups
+ * @param[out] pickups if @a fpu is true, set to details about the pickup operations
+ * @return transaction status,
+ * #TALER_EC_TIP_AUTHORIZE_RESERVE_EXPIRED if the reserve is known but has expired
+ * #TALER_EC_TIP_AUTHORIZE_RESERVE_UNKNOWN if the reserve is not known
+ * #TALER_EC_TIP_AUTHORIZE_INSUFFICIENT_FUNDS if the reserve has insufficient funds left
+ * #TALER_EC_TIP_AUTHORIZE_DB_HARD_ERROR on hard DB errors
+ * #TALER_EC_TIP_AUTHORIZE_DB_SOFT_ERROR on soft DB errors (client should retry)
+ * #TALER_EC_NONE upon success
+ */
+static enum TALER_ErrorCode
+postgres_lookup_tip_details (void *cls,
+ const char *instance_id,
+ const struct GNUNET_HashCode tip_id,
+ bool fpu,
+ struct TALER_Amount *total_authorized,
+ struct TALER_Amount *total_picked_up,
+ char **justification,
+ struct GNUNET_TIME_Absolute *expiration,
+ struct TALER_ReservePublicKeyP *reserve_pub,
+ unsigned int *pickups_length,
+ struct TALER_MERCHANTDB_PickupDetails **pickups)
+{
+}
+
+
+/**
+ * Insert details about a tip pickup operation. The @a total_picked_up
+ * UPDATES the total amount under the @a tip_id, while the @a
+ * total_requested is the amount to be associated with this @a pickup_id.
+ * While there is usually only one pickup event that picks up the entire
+ * amount, our schema allows for wallets to pick up the amount incrementally
+ * over multiple pick up operations.
+ *
+ * @param cls closure, typically a connection to the db
+ * @param tip_id the unique ID for the tip
+ * @param total_picked_up how much was picked up overall at this
+ * point (includes @total_requested)
+ * @param pickup_id unique ID for the operation
+ * @param total_requested how much is being picked up in this operation
+ * @return transaction status, usually
+ * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT for success
+ * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if @a credit_uuid already known
+ */
+static enum GNUNET_DB_QueryStatus
+postgres_insert_pickup (void *cls,
+ const char *instance_id,
+ const struct GNUNET_HashCode *tip_id,
+ const struct TALER_Amount *total_picked_up,
+ const struct GNUNET_HashCode *pickup_id,
+ const struct TALER_Amount *total_requested)
+{
+ struct PostgresClosure *pg = cls;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_string (instance_id),
+ GNUNET_PQ_query_param_auto_from_type (tip_id),
+ TALER_PQ_query_param_amount (total_picked_up),
+ GNUNET_PQ_query_param_auto_from_type (pickup_id),
+ TALER_PQ_query_param_amount (total_requested),
+ GNUNET_PQ_query_param_end
+ };
+
+ check_connection (pg);
+ return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "insert_pickup", // FIXME: write SQL!
+ params);
+}
+
+
+/**
+ * Insert blind signature obtained from the exchange during a
+ * tip pickup operation.
+ *
+ * @param cls closure, typically a connection to the db
+ * @param pickup_id unique ID for the operation
+ * @param offset offset of the blind signature for the pickup
+ * @param blind_sig the blind signature
+ * @return transaction status, usually
+ * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT for success
+ * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if @a credit_uuid already known
+ */
+static enum GNUNET_DB_QueryStatus
+postgres_insert_pickup_blind_signature (
+ void *cls,
+ const struct GNUNET_HashCode *pickup_id,
+ uint32_t offset,
+ const struct GNUNET_CRYPTO_RsaSignature *blind_sig)
+{
+ struct PostgresClosure *pg = cls;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (pickup_id),
+ GNUNET_PQ_query_param_uint32 (&offset),
+ GNUNET_PQ_query_param_rsa_signature (blind_sig),
+ GNUNET_PQ_query_param_end
+ };
+
+ check_connection (pg);
+ return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "insert_pickup_blind_signature", // FIXME: write SQL!
+ params);
+}
+
+
/* ********************* OLD API ************************** */
/**
@@ -7228,7 +7518,15 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
plugin->lookup_reserve = &postgres_lookup_reserve;
plugin->delete_reserve = &postgres_delete_reserve;
plugin->purge_reserve = &postgres_purge_reserve;
-/* OLD API: */
+ plugin->authorize_tip = &postgres_authorize_tip;
+ plugin->lookup_pickup = &postgres_lookup_pickup;
+ plugin->lookup_tip = &postgres_lookup_tip;
+ plugin->lookup_tip_details = &postgres_lookup_tip_details;
+ plugin->insert_pickup = &postgres_insert_pickup;
+ plugin->insert_pickup_blind_signature =
+ &postgres_insert_pickup_blind_signature;
+ /* OLD API: */
+
plugin->store_coin_to_transfer = &postgres_store_coin_to_transfer;
plugin->store_transfer_to_proof = &postgres_store_transfer_to_proof;
plugin->store_wire_fee_by_exchange = &postgres_store_wire_fee_by_exchange;