diff options
author | Christian Grothoff <christian@grothoff.org> | 2022-04-04 20:42:26 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2022-04-04 20:42:26 +0200 |
commit | 71916414069d18ec5b7d5901d52d62a2aaa1403d (patch) | |
tree | 358aa66952249b086fadc200bd3ecf895c62c473 /src | |
parent | df8ff01f2924f557096ec24ff650aefbf7931784 (diff) |
implement more DB functions
Diffstat (limited to 'src')
-rw-r--r-- | src/exchangedb/plugin_exchangedb_postgres.c | 389 | ||||
-rw-r--r-- | src/include/taler_exchangedb_plugin.h | 4 |
2 files changed, 299 insertions, 94 deletions
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index bc6da918c..64cc0a77e 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -592,6 +592,21 @@ prepare_statements (struct PostgresClosure *pg) " WHERE wire_target_h_payto=$1" " LIMIT 1;", 1), + /* Used in #postgres_insert_partner() */ + GNUNET_PQ_make_prepare ( + "insert_partner", + "INSERT INTO partners" + " (partner_master_pub" + " ,start_date" + " ,end_date" + " ,wad_frequency" + " ,wad_fee_val" + " ,wad_fee_frac" + " ,master_sig" + " ,partner_base_url" + " ) VALUES " + " ($1, $2, $3, $4, $5, $6, $7, $8);", + 8), /* Used in #postgres_inselect_wallet_kyc_status() */ GNUNET_PQ_make_prepare ( "insert_kyc_status", @@ -3254,22 +3269,6 @@ prepare_statements (struct PostgresClosure *pg) "FROM extensions" " WHERE name=$1;", 1), - - /* Used in #postgres_insert_partner() */ - GNUNET_PQ_make_prepare ( - "insert_partner", - "INSERT INTO partners" - " (partner_master_pub" - " ,start_date" - " ,end_date" - " ,wad_frequency" - " ,wad_fee_val" - " ,wad_fee_frac" - " ,master_sig" - " ,partner_base_url" - " ) VALUES " - " ($1, $2, $3, $4, $5, $6, $7, $8);", - 8), /* Used in #postgres_insert_contract() */ GNUNET_PQ_make_prepare ( "insert_contract", @@ -3277,12 +3276,14 @@ prepare_statements (struct PostgresClosure *pg) " (purse_pub" " ,pub_ckey" " ,e_contract" + " ,contract_sig" " ,purse_expiration" " ) SELECT " - " $1, $2, $3, purse_expiration" + " $1, $2, $3, $4, purse_expiration" " FROM purse_requests" - " WHERE purse_pub=$1;", - 3), + " WHERE purse_pub=$1" + " ON CONFLICT DO NOTHING;", + 4), /* Used in #postgres_select_contract */ GNUNET_PQ_make_prepare ( "select_contract", @@ -3306,8 +3307,9 @@ prepare_statements (struct PostgresClosure *pg) " ,amount_with_fee_frac" " ,purse_sig" " ) VALUES " - " ($1, $2, $3, $4, $5, $6, $7, $8);", - 7), + " ($1, $2, $3, $4, $5, $6, $7, $8)" + " ON CONFLICT DO NOTHING;", + 8), /* Used in #postgres_select_purse_request */ GNUNET_PQ_make_prepare ( "select_purse_request", @@ -3318,10 +3320,28 @@ prepare_statements (struct PostgresClosure *pg) ",age_limit" ",amount_with_fee_val" ",amount_with_fee_frac" + ",balance_val" + ",balance_frac" ",purse_sig" " FROM purse_requests" " WHERE purse_pub=$1;", 1), + /* Used in #postgres_select_purse_by_merge_pub */ + GNUNET_PQ_make_prepare ( + "select_purse_by_merge_pub", + "SELECT " + " purse_pub" + ",purse_expiration" + ",h_contract_terms" + ",age_limit" + ",amount_with_fee_val" + ",amount_with_fee_frac" + ",balance_val" + ",balance_frac" + ",purse_sig" + " FROM purse_requests" + " WHERE merge_pub=$1;", + 1), /* Used in #postgres_do_purse_deposit() */ GNUNET_PQ_make_prepare ( "call_purse_deposit", @@ -12723,9 +12743,10 @@ postgres_set_extension_config (void *cls, const char *config) { struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam pcfg = (NULL == config || 0 == *config) ? - GNUNET_PQ_query_param_null () : - GNUNET_PQ_query_param_string (config); + struct GNUNET_PQ_QueryParam pcfg = + (NULL == config || 0 == *config) + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (config); struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_string (extension_name), pcfg, @@ -12758,20 +12779,19 @@ postgres_get_extension_config (void *cls, GNUNET_PQ_query_param_end }; bool is_null; - *config = NULL; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_allow_null ( - GNUNET_PQ_result_spec_string ("config", config), + GNUNET_PQ_result_spec_string ("config", + config), &is_null), GNUNET_PQ_result_spec_end }; - enum GNUNET_DB_QueryStatus qs; - qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, - "get_extension_config", - params, - rs); - return qs; + *config = NULL; + return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, + "get_extension_config", + params, + rs); } @@ -12799,38 +12819,21 @@ postgres_insert_partner (void *cls, const char *partner_base_url, const struct TALER_MasterSignatureP *master_sig) { - GNUNET_break (0); - return GNUNET_DB_STATUS_HARD_ERROR; -} - + struct PostgresClosure *pg = cls; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (master_pub), + GNUNET_PQ_query_param_timestamp (&start_date), + GNUNET_PQ_query_param_timestamp (&end_date), + GNUNET_PQ_query_param_relative_time (&wad_frequency), + TALER_PQ_query_param_amount (wad_fee), + GNUNET_PQ_query_param_auto_from_type (master_sig), + GNUNET_PQ_query_param_string (partner_base_url), + GNUNET_PQ_query_param_end + }; -/** - * Function called to persist an encrypted contract associated with a reserve. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param purse_pub the purse the contract is associated with (must exist) - * @param pub_ckey ephemeral key for DH used to encrypt the contract - * @param econtract_size number of bytes in @a econtract - * @param econtract the encrypted contract - * @param[out] econtract_sig set to the signature over the encrypted contract - * @param[out] in_conflict set to true if @a econtract - * conflicts with an existing contract; - * in this case, the return value will be - * #GNUNET_DB_STATUS_SUCCESS_ONE despite the failure - * @return transaction status code - */ -static enum GNUNET_DB_QueryStatus -postgres_insert_contract (void *cls, - const struct TALER_PurseContractPublicKeyP *purse_pub, - const struct TALER_ContractDiffiePublicP *pub_ckey, - size_t econtract_size, - const void *econtract, - const struct - TALER_PurseContractSignatureP *econtract_sig, - bool *in_conflict) -{ - GNUNET_break (0); - return GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_PQ_eval_prepared_non_select (pg->conn, + "insert_partner", + params); } @@ -12853,42 +12856,101 @@ postgres_select_contract (void *cls, size_t *econtract_size, void **econtract) { - GNUNET_break (0); - return GNUNET_DB_STATUS_HARD_ERROR; + struct PostgresClosure *pg = cls; + + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (purse_pub), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("pub_ckey", + pub_ckey), + GNUNET_PQ_result_spec_auto_from_type ("contract_sig", + econtract_sig), + GNUNET_PQ_result_spec_variable_size ("econtract", + econtract, + econtract_size), + GNUNET_PQ_result_spec_end + }; + return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, + "select_contract", + params, + rs); + } /** - * Function called to create a new purse with certain meta data. + * Function called to persist an encrypted contract associated with a reserve. * * @param cls the @e cls of this struct with the plugin-specific state - * @param purse_pub public key of the new purse - * @param merge_pub public key providing the merge capability - * @param purse_expiration time when the purse will expire - * @param h_contract_terms hash of the contract for the purse - * @param age_limit age limit to enforce for payments into the purse - * @param amount target amount (with fees) to be put into the purse - * @param purse_sig signature with @a purse_pub's private key affirming the above - * @param[out] in_conflict set to true if the meta data - * conflicts with an existing purse; + * @param purse_pub the purse the contract is associated with (must exist) + * @param pub_ckey ephemeral key for DH used to encrypt the contract + * @param econtract_size number of bytes in @a econtract + * @param econtract the encrypted contract + * @param[out] econtract_sig set to the signature over the encrypted contract + * @param[out] in_conflict set to true if @a econtract + * conflicts with an existing contract; * in this case, the return value will be * #GNUNET_DB_STATUS_SUCCESS_ONE despite the failure * @return transaction status code */ static enum GNUNET_DB_QueryStatus -postgres_insert_purse_request ( +postgres_insert_contract ( void *cls, const struct TALER_PurseContractPublicKeyP *purse_pub, - const struct TALER_PurseMergePublicKeyP *merge_pub, - struct GNUNET_TIME_Timestamp purse_expiration, - const struct TALER_PrivateContractHashP *h_contract_terms, - uint32_t age_limit, - const struct TALER_Amount *amount, - const struct TALER_PurseContractSignatureP *purse_sig, + const struct TALER_ContractDiffiePublicP *pub_ckey, + size_t econtract_size, + const void *econtract, + const struct TALER_PurseContractSignatureP *econtract_sig, bool *in_conflict) { - GNUNET_break (0); - return GNUNET_DB_STATUS_HARD_ERROR; + struct PostgresClosure *pg = cls; + enum GNUNET_DB_QueryStatus qs; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (purse_pub), + GNUNET_PQ_query_param_auto_from_type (pub_ckey), + GNUNET_PQ_query_param_fixed_size (econtract, + econtract_size), + GNUNET_PQ_query_param_auto_from_type (econtract_sig), + GNUNET_PQ_query_param_end + }; + + *in_conflict = false; + qs = GNUNET_PQ_eval_prepared_non_select (pg->conn, + "insert_contract", + params); + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs) + return qs; + { + struct TALER_ContractDiffiePublicP pub_ckey2; + struct TALER_PurseContractSignatureP esig2; + size_t econtract_size2; + void *econtract2; + + qs = postgres_select_contract (pg, + purse_pub, + &pub_ckey2, + &esig2, + &econtract_size2, + &econtract2); + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + if ( (0 == GNUNET_memcmp (&pub_ckey2, + pub_ckey)) && + (econtract_size2 == econtract_size) && + (0 == memcmp (econtract2, + econtract, + econtract_size)) ) + { + return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; + } + *in_conflict = true; + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; + } } @@ -12901,6 +12963,7 @@ postgres_insert_purse_request ( * @param[out] merge_pub public key representing the merge capability * @param[out] purse_expiration when would an unmerged purse expire * @param[out] h_contract_terms contract associated with the purse + * @param[out] age_limit the age limit for deposits into the purse * @param[out] target_amount amount to be put into the purse * @param[out] balance amount put so far into the purse * @param[out] purse_sig signature of the purse over the initialization data @@ -12913,12 +12976,124 @@ postgres_select_purse_request ( struct TALER_PurseMergePublicKeyP *merge_pub, struct GNUNET_TIME_Timestamp *purse_expiration, struct TALER_PrivateContractHashP *h_contract_terms, + uint32_t *age_limit, struct TALER_Amount *target_amount, struct TALER_Amount *balance, struct TALER_PurseContractSignatureP *purse_sig) { - GNUNET_break (0); - return GNUNET_DB_STATUS_HARD_ERROR; + struct PostgresClosure *pg = cls; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (purse_pub), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("merge_pub", + merge_pub), + GNUNET_PQ_result_spec_timestamp ("purse_expiration", + purse_expiration), + GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", + h_contract_terms), + GNUNET_PQ_result_spec_uint32 ("age_limit", + age_limit), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + target_amount), + TALER_PQ_RESULT_SPEC_AMOUNT ("balance", + balance), + GNUNET_PQ_result_spec_auto_from_type ("purse_sig", + purse_sig), + GNUNET_PQ_result_spec_end + }; + return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, + "select_purse_request", + params, + rs); +} + + +/** + * Function called to create a new purse with certain meta data. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub public key of the new purse + * @param merge_pub public key providing the merge capability + * @param purse_expiration time when the purse will expire + * @param h_contract_terms hash of the contract for the purse + * @param age_limit age limit to enforce for payments into the purse + * @param amount target amount (with fees) to be put into the purse + * @param purse_sig signature with @a purse_pub's private key affirming the above + * @param[out] in_conflict set to true if the meta data + * conflicts with an existing purse; + * in this case, the return value will be + * #GNUNET_DB_STATUS_SUCCESS_ONE despite the failure + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +postgres_insert_purse_request ( + void *cls, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseMergePublicKeyP *merge_pub, + struct GNUNET_TIME_Timestamp purse_expiration, + const struct TALER_PrivateContractHashP *h_contract_terms, + uint32_t age_limit, + const struct TALER_Amount *amount, + const struct TALER_PurseContractSignatureP *purse_sig, + bool *in_conflict) +{ + struct PostgresClosure *pg = cls; + enum GNUNET_DB_QueryStatus qs; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (purse_pub), + GNUNET_PQ_query_param_auto_from_type (merge_pub), + GNUNET_PQ_query_param_timestamp (&purse_expiration), + GNUNET_PQ_query_param_auto_from_type (h_contract_terms), + GNUNET_PQ_query_param_uint32 (&age_limit), + TALER_PQ_query_param_amount (amount), + GNUNET_PQ_query_param_auto_from_type (purse_sig), + GNUNET_PQ_query_param_end + }; + + *in_conflict = false; + qs = GNUNET_PQ_eval_prepared_non_select (pg->conn, + "insert_purse_request", + params); + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs) + return qs; + { + struct TALER_PurseMergePublicKeyP merge_pub2; + struct GNUNET_TIME_Timestamp purse_expiration2; + struct TALER_PrivateContractHashP h_contract_terms2; + uint32_t age_limit2; + struct TALER_Amount amount2; + struct TALER_Amount balance; + struct TALER_PurseContractSignatureP purse_sig2; + + qs = postgres_select_purse_request (pg, + purse_pub, + &merge_pub2, + &purse_expiration2, + &h_contract_terms2, + &age_limit2, + &amount2, + &balance, + &purse_sig2); + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + if ( (age_limit2 == age_limit) && + (0 == TALER_amount_cmp (amount, + &amount2)) && + (0 == GNUNET_memcmp (&h_contract_terms2, + h_contract_terms)) && + (0 == GNUNET_memcmp (&merge_pub2, + merge_pub)) ) + { + return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; + } + *in_conflict = true; + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; + } } @@ -12931,6 +13106,7 @@ postgres_select_purse_request ( * @param[out] purse_pub public key of the purse * @param[out] purse_expiration when would an unmerged purse expire * @param[out] h_contract_terms contract associated with the purse + * @param[out] age_limit the age limit for deposits into the purse * @param[out] target_amount amount to be put into the purse * @param[out] balance amount put so far into the purse * @param[out] purse_sig signature of the purse over the initialization data @@ -12943,12 +13119,37 @@ postgres_select_purse_by_merge_pub ( struct TALER_PurseContractPublicKeyP *purse_pub, struct GNUNET_TIME_Timestamp *purse_expiration, struct TALER_PrivateContractHashP *h_contract_terms, + uint32_t *age_limit, struct TALER_Amount *target_amount, struct TALER_Amount *balance, struct TALER_PurseContractSignatureP *purse_sig) { - GNUNET_break (0); - return GNUNET_DB_STATUS_HARD_ERROR; + struct PostgresClosure *pg = cls; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (merge_pub), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("purse_pub", + purse_pub), + GNUNET_PQ_result_spec_timestamp ("purse_expiration", + purse_expiration), + GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", + h_contract_terms), + GNUNET_PQ_result_spec_uint32 ("age_limit", + age_limit), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + target_amount), + TALER_PQ_RESULT_SPEC_AMOUNT ("balance", + balance), + GNUNET_PQ_result_spec_auto_from_type ("purse_sig", + purse_sig), + GNUNET_PQ_result_spec_end + }; + return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, + "select_purse_by_merge_pub", + params, + rs); } @@ -12982,7 +13183,7 @@ postgres_do_purse_deposit ( const struct TALER_Amount *amount_minus_fee, bool *balance_ok) { - GNUNET_break (0); + GNUNET_break (0); // FIXME return GNUNET_DB_STATUS_HARD_ERROR; } @@ -13008,7 +13209,7 @@ postgres_do_purse_merge ( const char *partner_url, const struct TALER_ReservePublicKeyP *reserve_pub) { - GNUNET_break (0); + GNUNET_break (0); // FIXME return GNUNET_DB_STATUS_HARD_ERROR; } @@ -13034,7 +13235,7 @@ postgres_select_purse_merge ( char **partner_url, struct TALER_ReservePublicKeyP *reserve_pub) { - GNUNET_break (0); + GNUNET_break (0); // FIXME return GNUNET_DB_STATUS_HARD_ERROR; } @@ -13056,7 +13257,7 @@ postgres_do_account_merge ( const struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_ReserveSignatureP *reserve_sig) { - GNUNET_break (0); + GNUNET_break (0); // FIXME return GNUNET_DB_STATUS_HARD_ERROR; } @@ -13082,7 +13283,7 @@ postgres_insert_history_request ( struct GNUNET_TIME_Absolute request_timestamp, const struct TALER_Amount *history) { - GNUNET_break (0); + GNUNET_break (0); // FIXME return GNUNET_DB_STATUS_HARD_ERROR; } @@ -13103,7 +13304,7 @@ postgres_insert_close_request ( const struct TALER_ReserveSignatureP *reserve_sig, struct TALER_Amount *final_balance) { - GNUNET_break (0); + GNUNET_break (0); // FIXME return GNUNET_DB_STATUS_HARD_ERROR; } diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index 1e56c5e0d..9c9410d66 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -4502,6 +4502,7 @@ struct TALER_EXCHANGEDB_Plugin * @param[out] merge_pub public key representing the merge capability * @param[out] purse_expiration when would an unmerged purse expire * @param[out] h_contract_terms contract associated with the purse + * @param[out] age_limit the age limit for deposits into the purse * @param[out] target_amount amount to be put into the purse * @param[out] balance amount put so far into the purse * @param[out] purse_sig signature of the purse over the initialization data @@ -4514,6 +4515,7 @@ struct TALER_EXCHANGEDB_Plugin struct TALER_PurseMergePublicKeyP *merge_pub, struct GNUNET_TIME_Timestamp *purse_expiration, struct TALER_PrivateContractHashP *h_contract_terms, + uint32_t *age_limit, struct TALER_Amount *target_amount, struct TALER_Amount *balance, struct TALER_PurseContractSignatureP *purse_sig); @@ -4528,6 +4530,7 @@ struct TALER_EXCHANGEDB_Plugin * @param[out] purse_pub public key of the purse * @param[out] purse_expiration when would an unmerged purse expire * @param[out] h_contract_terms contract associated with the purse + * @param[out] age_limit the age limit for deposits into the purse * @param[out] target_amount amount to be put into the purse * @param[out] balance amount put so far into the purse * @param[out] purse_sig signature of the purse over the initialization data @@ -4540,6 +4543,7 @@ struct TALER_EXCHANGEDB_Plugin struct TALER_PurseContractPublicKeyP *purse_pub, struct GNUNET_TIME_Timestamp *purse_expiration, struct TALER_PrivateContractHashP *h_contract_terms, + uint32_t *age_limit, struct TALER_Amount *target_amount, struct TALER_Amount *balance, struct TALER_PurseContractSignatureP *purse_sig); |