diff options
author | Christian Grothoff <christian@grothoff.org> | 2020-05-23 11:05:58 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2020-05-23 11:05:58 +0200 |
commit | 5ee782667a2ceb3088a1da2076f6047dc5fb4eaf (patch) | |
tree | 9e3a01daafff4f07dad67c1489ac8639da12fef9 /src/backenddb | |
parent | 49157c0beaeae761cac5daa22d8734880ee726dd (diff) | |
download | merchant-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.c | 300 |
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; |