diff --git a/src/exchangedb/drop0001.sql b/src/exchangedb/drop0001.sql index c969286a0..60acc98a4 100644 --- a/src/exchangedb/drop0001.sql +++ b/src/exchangedb/drop0001.sql @@ -33,6 +33,7 @@ DROP TRIGGER IF EXISTS deposits_on_insert ON deposits; DROP TRIGGER IF EXISTS deposits_on_delete ON deposits; DROP TRIGGER IF EXISTS recoup_on_insert ON recoup; DROP TRIGGER IF EXISTS recoup_on_delete ON recoup; + DROP TABLE IF EXISTS revolving_work_shards CASCADE; DROP TABLE IF EXISTS extensions CASCADE; DROP TABLE IF EXISTS auditors CASCADE; @@ -85,50 +86,45 @@ DROP TABLE IF EXISTS recoup_by_reserve CASCADE; DROP TABLE IF EXISTS partners CASCADE; -DROP TABLE IF EXISTS mergers CASCADE; +DROP TABLE IF EXISTS account_merges CASCADE; +DROP TABLE IF EXISTS purse_merges CASCADE; DROP TABLE IF EXISTS contracts CASCADE; DROP TABLE IF EXISTS history_requests CASCADE; DROP TABLE IF EXISTS close_requests CASCADE; DROP TABLE IF EXISTS purse_requests CASCADE; DROP TABLE IF EXISTS wads_out CASCADE; -DROP TABLE IF EXISTS wads_out_entries CASCADE; +DROP TABLE IF EXISTS wad_out_entries CASCADE; DROP TABLE IF EXISTS wads_in CASCADE; -DROP TABLE IF EXISTS wads_in_entries CASCADE; +DROP TABLE IF EXISTS wad_in_entries CASCADE; DROP TABLE IF EXISTS partner_accounts CASCADE; DROP FUNCTION IF EXISTS exchange_do_withdraw; DROP FUNCTION IF EXISTS exchange_do_withdraw_limit_check; - DROP FUNCTION IF EXISTS recoup_insert_trigger; DROP FUNCTION IF EXISTS recoup_delete_trigger; DROP FUNCTION IF EXISTS deposits_by_coin_insert_trigger; DROP FUNCTION IF EXISTS deposits_by_coin_delete_trigger; DROP FUNCTION IF EXISTS reserves_out_by_reserve_insert_trigger; DROP FUNCTION IF EXISTS reserves_out_by_reserve_delete_trigger; - DROP FUNCTION IF EXISTS exchange_do_deposit; - DROP FUNCTION IF EXISTS exchange_do_melt; - DROP FUNCTION IF EXISTS exchange_do_refund; - DROP FUNCTION IF EXISTS exchange_do_recoup_to_coin; - DROP FUNCTION IF EXISTS exchange_do_recoup_to_reserve; - --- FIXME: drop other stored functions! +DROP FUNCTION IF EXISTS exchange_do_purse_deposit; +DROP FUNCTION IF EXISTS exchange_do_purse_merge; +DROP FUNCTION IF EXISTS exchange_do_account_merge; +DROP FUNCTION IF EXISTS exchange_do_history_request; +DROP FUNCTION IF EXISTS exchange_do_close_request; -- Unregister patch (partition-0001.sql) -- SELECT _v.unregister_patch('partition-0001'); -- Drops for partition-0001.sql DROP FUNCTION IF EXISTS create_table_partition; - DROP FUNCTION IF EXISTS create_partitions; - DROP FUNCTION IF EXISTS detach_default_partitions; - DROP FUNCTION IF EXISTS drop_default_partitions; diff --git a/src/exchangedb/exchange-0001.sql b/src/exchangedb/exchange-0001.sql index 5a4199040..5acb8995b 100644 --- a/src/exchangedb/exchange-0001.sql +++ b/src/exchangedb/exchange-0001.sql @@ -787,7 +787,7 @@ END $$; COMMENT ON FUNCTION deposits_by_coin_delete_trigger() IS 'Replicate deposits deletions into deposits_by_coin table.'; -CREATE TRIGGER deposit_on_delete +CREATE TRIGGER deposits_on_delete AFTER DELETE ON deposits FOR EACH ROW EXECUTE FUNCTION deposits_by_coin_delete_trigger(); @@ -1410,10 +1410,11 @@ CREATE TABLE IF NOT EXISTS purse_requests ,merge_pub BYTEA NOT NULL CHECK (LENGTH(merge_pub)=32) ,purse_expiration INT8 NOT NULL ,h_contract_terms BYTEA NOT NULL CHECK (LENGTH(h_contract_terms)=64) + ,age_limit INT4 NOT NULL ,amount_with_fee_val INT8 NOT NULL ,amount_with_fee_frac INT4 NOT NULL - ,balance_val INT8 NOT NULL - ,balance_frac INT4 NOT NULL + ,balance_val INT8 NOT NULL DEFAULT (0) + ,balance_frac INT4 NOT NULL DEFAULT (0) ,purse_sig BYTEA NOT NULL CHECK(LENGTH(purse_sig)=64) ,PRIMARY KEY (purse_pub) ); -- partition by purse_pub @@ -1432,6 +1433,9 @@ COMMENT ON COLUMN purse_requests.balance_val COMMENT ON COLUMN purse_requests.purse_sig IS 'Signature of the purse affirming the purse parameters, of type TALER_SIGNATURE_PURSE_REQUEST'; +-- FIXME: create purse_by_merge materialized index table +-- for merge_pub => purse_pub mapping! + CREATE TABLE IF NOT EXISTS purse_merges (purse_merge_request_serial_id BIGSERIAL -- UNIQUE @@ -1487,6 +1491,7 @@ CREATE TABLE IF NOT EXISTS contracts ,purse_pub BYTEA NOT NULL CHECK (LENGTH(purse_pub)=32) ,pub_ckey BYTEA NOT NULL CHECK (LENGTH(pub_ckey)=32) ,e_contract BYTEA NOT NULL + ,purse_expiration INT8 NOT NULL ,PRIMARY KEY (purse_pub) ); -- partition by purse_pub COMMENT ON TABLE contracts @@ -2899,5 +2904,85 @@ DELETE FROM cs_nonce_locks END $$; + + + + + + + +CREATE OR REPLACE FUNCTION exchange_do_purse_deposit( + IN in_purse_pub BYTEA, + IN in_amount_with_fee_val INT8, + IN in_amount_with_fee_frac INT4, + IN in_coin_pub BYTEA, + IN in_coin_sig BYTEA, + OUT out_balance_ok BOOLEAN, + OUT out_conflict BOOLEAN) +LANGUAGE plpgsql +AS $$ +BEGIN + -- FIXME +END $$; + + +CREATE OR REPLACE FUNCTION exchange_do_purse_merge( + IN in_purse_pub BYTEA, + IN in_merge_sig BYTEA, + IN in_merge_timestamp INT8, + IN in_partner_url VARCHAR, + IN in_reserve_pub BYTEA, + OUT out_balance_ok BOOLEAN, + OUT out_conflict BOOLEAN) +LANGUAGE plpgsql +AS $$ +BEGIN + -- FIXME +END $$; + + +CREATE OR REPLACE FUNCTION exchange_do_account_merge( + IN in_purse_pub BYTEA, + IN in_reserve_pub BYTEA, + IN in_reserve_sig BYTEA, + OUT out_balance_ok BOOLEAN, + OUT out_conflict BOOLEAN) +LANGUAGE plpgsql +AS $$ +BEGIN + -- FIXME +END $$; + + +CREATE OR REPLACE FUNCTION exchange_do_history_request( + IN in_reserve_pub BYTEA, + IN in_reserve_sig BYTEA, + IN in_request_timestamp INT8, + IN in_history_fee_val INT8, + IN in_history_fee_frac INT4, + OUT out_balance_ok BOOLEAN, + OUT out_conflict BOOLEAN) +LANGUAGE plpgsql +AS $$ +BEGIN + -- FIXME +END $$; + + +CREATE OR REPLACE FUNCTION exchange_do_close_request( + IN in_reserve_pub BYTEA, + IN in_reserve_sig BYTEA, + OUT out_final_balance_val INT8, + OUT out_final_balance_frac INT4, + OUT out_balance_ok BOOLEAN, + OUT out_conflict BOOLEAN) +LANGUAGE plpgsql +AS $$ +BEGIN + -- FIXME +END $$; + + + -- Complete transaction COMMIT; diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index 3f8716261..54bea9af9 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -3068,6 +3068,124 @@ 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", + "INSERT INTO contracts" + " (purse_pub" + " ,pub_ckey" + " ,e_contract" + " ,purse_expiration" + " ) SELECT " + " $1, $2, $3, purse_expiration" + " FROM purse_requests" + " WHERE purse_pub=$1;", + 3), + /* Used in #postgres_select_contract */ + GNUNET_PQ_make_prepare ( + "select_contract", + "SELECT " + " pub_ckey" + ",e_contract" + " FROM contracts" + " WHERE purse_pub=$1;", + 1), + /* Used in #postgres_insert_purse_request() */ + GNUNET_PQ_make_prepare ( + "insert_purse_request", + "INSERT INTO purse_requests" + " (purse_pub" + " ,merge_pub" + " ,purse_expiration" + " ,h_contract_terms" + " ,age_limit" + " ,amount_with_fee_val" + " ,amount_with_fee_frac" + " ,purse_sig" + " ) VALUES " + " ($1, $2, $3, $4, $5, $6, $7, $8);", + 7), + /* Used in #postgres_select_purse_request */ + GNUNET_PQ_make_prepare ( + "select_purse_request", + "SELECT " + " merge_pub" + ",purse_expiration" + ",h_contract_terms" + ",age_limit" + ",amount_with_fee_val" + ",amount_with_fee_frac" + ",purse_sig" + " FROM purse_requests" + " WHERE purse_pub=$1;", + 1), + /* Used in #postgres_do_purse_deposit() */ + GNUNET_PQ_make_prepare ( + "call_purse_deposit", + "SELECT 1" + " FROM exchange_do_purse_deposit" + " ($1, $2, $3, $4, $5);", + 5), + /* Used in #postgres_do_purse_merge() */ + GNUNET_PQ_make_prepare ( + "call_purse_merge", + "SELECT 1" + " FROM exchange_do_purse_merge" + " ($1, $2, $3, $4, $5);", + 5), + /* Used in #postgres_select_purse_merge */ + GNUNET_PQ_make_prepare ( + "select_purse_merge", + "SELECT " + " reserve_pub" + ",purse_pub" + ",merge_sig" + ",merge_timestamp" + ",partner_base_url" + " FROM purse_merges" + " JOIN partners USING (partner_serial_id)" + " WHERE purse_pub=$1;", + 1), + /* Used in #postgres_do_account_merge() */ + GNUNET_PQ_make_prepare ( + "call_account_merge", + "SELECT 1" + " FROM exchange_do_account_merge" + " ($1, $2, $3);", + 3), + /* Used in #postgres_insert_history_request() */ + GNUNET_PQ_make_prepare ( + "call_history_request", + "SELECT 1" + " FROM exchange_do_history_request" + " ($1, $2, $3, $4, $5)", + 5), + /* Used in #postgres_insert_close_request() */ + GNUNET_PQ_make_prepare ( + "call_account_close", + "SELECT " + " out_final_balance_val" + ",out_final_balance_frac" + " FROM exchange_do_close_request" + " ($1, $2)", + 2), + GNUNET_PQ_PREPARED_STATEMENT_END }; @@ -9946,7 +10064,7 @@ struct RecoupRefreshSerialContext /** * Status code, set to #GNUNET_SYSERR on hard errors. */ - int status; + enum GNUNET_GenericReturnValue status; }; @@ -10102,7 +10220,7 @@ struct ReserveClosedSerialContext /** * Status code, set to #GNUNET_SYSERR on hard errors. */ - int status; + enum GNUNET_GenericReturnValue status; }; @@ -10148,7 +10266,7 @@ reserve_closed_serial_helper_cb (void *cls, &closing_fee), GNUNET_PQ_result_spec_end }; - int ret; + enum GNUNET_GenericReturnValue ret; if (GNUNET_OK != GNUNET_PQ_extract_result (result, @@ -10377,7 +10495,7 @@ struct MissingWireContext /** * Set to #GNUNET_SYSERR on error. */ - int status; + enum GNUNET_GenericReturnValue status; }; @@ -10737,7 +10855,7 @@ struct GetWireAccountsContext /** * Flag set to #GNUNET_OK as long as everything is fine. */ - int status; + enum GNUNET_GenericReturnValue status; }; @@ -10844,7 +10962,7 @@ struct GetWireFeesContext /** * Flag set to #GNUNET_OK as long as everything is fine. */ - int status; + enum GNUNET_GenericReturnValue status; }; @@ -12526,6 +12644,317 @@ postgres_get_extension_config (void *cls, } +/** + * Function called to store configuration data about a partner + * exchange that we are federated with. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param master_pub public offline signing key of the partner exchange + * @param start_date when does the following data start to be valid + * @param end_date when does the validity end (exclusive) + * @param wad_frequency how often do we do exchange-to-exchange settlements? + * @param wad_fee how much do we charge for transfers to the partner + * @param partner_base_url base URL of the partner exchange + * @param master_sig signature with our offline signing key affirming the above + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +postgres_insert_partner (void *cls, + const struct TALER_MasterPublicKeyP *master_pub, + struct GNUNET_TIME_Timestamp start_date, + struct GNUNET_TIME_Timestamp end_date, + struct GNUNET_TIME_Relative wad_frequency, + const struct TALER_Amount *wad_fee, + const char *partner_base_url, + const struct TALER_MasterSignatureP *master_sig) +{ + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; +} + + +/** + * 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 + * @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) +{ + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; +} + + +/** + * Function called to retrieve an encrypted contract. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub key to lookup the contract by + * @param[out] pub_ckey set to the ephemeral DH used to encrypt the contract + * @param[out] econtract_size set to the number of bytes in @a econtract + * @param[out] econtract set to the encrypted contract on success, to be freed by the caller + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +postgres_select_contract (void *cls, + const struct TALER_PurseContractPublicKeyP *purse_pub, + struct TALER_ContractDiffiePublicP *pub_ckey, + size_t *econtract_size, + void **econtract) +{ + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; +} + + +/** + * 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 + * @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) +{ + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; +} + + +/** + * Function called to reutrn meta data about a purse by the + * purse public key. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub public key of the purse + * @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] 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 + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +postgres_select_purse_request ( + void *cls, + const struct TALER_PurseContractPublicKeyP *purse_pub, + struct TALER_PurseMergePublicKeyP *merge_pub, + struct GNUNET_TIME_Timestamp *purse_expiration, + struct TALER_PrivateContractHashP *h_contract_terms, + struct TALER_Amount *target_amount, + struct TALER_Amount *balance, + struct TALER_PurseContractSignatureP *purse_sig) +{ + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; +} + + +/** + * Function called to return meta data about a purse by the + * merge capability key. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param merge_pub public key representing the merge capability + * @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] 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 + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +postgres_select_purse_by_merge_pub ( + void *cls, + const struct TALER_PurseMergePublicKeyP *merge_pub, + struct TALER_PurseContractPublicKeyP *purse_pub, + struct GNUNET_TIME_Timestamp *purse_expiration, + struct TALER_PrivateContractHashP *h_contract_terms, + struct TALER_Amount *target_amount, + struct TALER_Amount *balance, + struct TALER_PurseContractSignatureP *purse_sig) +{ + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; +} + + +/** + * Function called to execute a transaction crediting + * a purse with @a amount from @a coin_pub. Reduces the + * value of @a coin_pub and increase the balance of + * the @a purse_pub purse. If the balance reaches the + * target amount and the purse has been merged, triggers + * the updates of the reserve/account balance. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub purse to credit + * @param coin_pub coin to deposit (debit) + * @param amount fraction of the coin's value to deposit + * @param coin_sig signature affirming the operation + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +postgres_do_purse_deposit ( + void *cls, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_Amount *amount, + const struct TALER_CoinSpendSignatureP *coin_sig) +{ + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; +} + + +/** + * Function called to approve merging a purse into a + * reserve by the respective purse merge key. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub purse to merge + * @param merge_sig signature affirming the merge + * @param merge_timestamp time of the merge + * @param partner_url URL of the partner exchange, can be NULL if the reserves lives with us + * @param reserve_pub public key of the reserve to credit + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +postgres_do_purse_merge ( + void *cls, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseMergeSignatureP *merge_sig, + const struct GNUNET_TIME_Timestamp merge_timestamp, + const char *partner_url, + const struct TALER_ReservePublicKeyP *reserve_pub) +{ + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; +} + + +/** + * Function called to approve merging of a purse with + * an account, made by the receiving account. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub public key of the purse + * @param[out] merge_sig set to the signature confirming the merge + * @param[out] merge_timestamp set to the time of the merge + * @param[out] partner_url set to the URL of the target exchange, or NULL if the target exchange is us. To be freed by the caller. + * @param[out] reserve_pub set to the public key of the reserve/account being credited + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +postgres_select_purse_merge ( + void *cls, + const struct TALER_PurseContractPublicKeyP *purse_pub, + struct TALER_PurseMergeSignatureP *merge_sig, + struct GNUNET_TIME_Timestamp *merge_timestamp, + char **partner_url, + struct TALER_ReservePublicKeyP *reserve_pub) +{ + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; +} + + +/** + * Function called to approve merging of a purse with + * an account, made by the receiving account. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub public key of the purse being merged + * @param reserve_pub public key of the account being credited + * @param reserve_sig signature of the account holder affirming the merge + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +postgres_do_account_merge ( + void *cls, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_ReserveSignatureP *reserve_sig) +{ + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; +} + + +/** + * Function called to persist a signature that + * prove that the client requested an + * account history. Debits the @a history_fee from + * the reserve (if possible). + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param reserve_pub account that the history was requested for + * @param reserve_sig signature affirming the request + * @param request_timestamp when was the request made + * @param history_fee how much should the @a reserve_pub be charged for the request + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +postgres_insert_history_request ( + void *cls, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_ReserveSignatureP *reserve_sig, + struct GNUNET_TIME_Absolute request_timestamp, + const struct TALER_Amount *history) +{ + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; +} + + +/** + * Function called to initiate closure of an account. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param reserve_pub public key of the account to close + * @param reserve_sig signature affiming that the account is to be closed + * @param[out] final_balance set to the final balance in the account that will be wired back to the origin account + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +postgres_insert_close_request ( + void *cls, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_ReserveSignatureP *reserve_sig, + struct TALER_Amount *final_balance) +{ + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; +} + + /** * Initialize Postgres database subsystem. * @@ -12772,6 +13201,30 @@ libtaler_plugin_exchangedb_postgres_init (void *cls) = &postgres_set_extension_config; plugin->get_extension_config = &postgres_get_extension_config; + plugin->insert_partner + = &postgres_insert_partner; + plugin->insert_contract + = &postgres_insert_contract; + plugin->select_contract + = &postgres_select_contract; + plugin->insert_purse_request + = &postgres_insert_purse_request; + plugin->select_purse_request + = &postgres_select_purse_request; + plugin->select_purse_by_merge_pub + = &postgres_select_purse_by_merge_pub; + plugin->do_purse_deposit + = &postgres_do_purse_deposit; + plugin->do_purse_merge + = &postgres_do_purse_merge; + plugin->select_purse_merge + = &postgres_select_purse_merge; + plugin->do_account_merge + = &postgres_do_account_merge; + plugin->insert_history_request + = &postgres_insert_history_request; + plugin->insert_close_request + = &postgres_insert_close_request; return plugin; } diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index 074e952ea..cee509542 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -4354,6 +4354,20 @@ struct TALER_EXCHANGEDB_Plugin char **config); + /** + * Function called to store configuration data about a partner + * exchange that we are federated with. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param master_pub public offline signing key of the partner exchange + * @param start_date when does the following data start to be valid + * @param end_date when does the validity end (exclusive) + * @param wad_frequency how often do we do exchange-to-exchange settlements? + * @param wad_fee how much do we charge for transfers to the partner + * @param partner_base_url base URL of the partner exchange + * @param master_sig signature with our offline signing key affirming the above + * @return transaction status code + */ enum GNUNET_DB_QueryStatus (*insert_partner)(void *cls, const struct TALER_MasterPublicKeyP *master_pub, @@ -4365,6 +4379,16 @@ struct TALER_EXCHANGEDB_Plugin const struct TALER_MasterSignatureP *master_sig); + /** + * 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 + * @return transaction status code + */ enum GNUNET_DB_QueryStatus (*insert_contract)(void *cls, const struct TALER_PurseContractPublicKeyP *purse_pub, @@ -4373,6 +4397,16 @@ struct TALER_EXCHANGEDB_Plugin const void *econtract); + /** + * Function called to retrieve an encrypted contract. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub key to lookup the contract by + * @param[out] pub_ckey set to the ephemeral DH used to encrypt the contract + * @param[out] econtract_size set to the number of bytes in @a econtract + * @param[out] econtract set to the encrypted contract on success, to be freed by the caller + * @return transaction status code + */ enum GNUNET_DB_QueryStatus (*select_contract)(void *cls, const struct TALER_PurseContractPublicKeyP *purse_pub, @@ -4381,6 +4415,19 @@ struct TALER_EXCHANGEDB_Plugin void **econtract); + /** + * 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 + * @return transaction status code + */ enum GNUNET_DB_QueryStatus (*insert_purse_request)( void *cls, @@ -4388,10 +4435,25 @@ struct TALER_EXCHANGEDB_Plugin 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); + /** + * Function called to reutrn meta data about a purse by the + * purse public key. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub public key of the purse + * @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] 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 + * @return transaction status code + */ enum GNUNET_DB_QueryStatus (*select_purse_request)( void *cls, @@ -4404,8 +4466,49 @@ struct TALER_EXCHANGEDB_Plugin struct TALER_PurseContractSignatureP *purse_sig); + /** + * Function called to return meta data about a purse by the + * merge capability key. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param merge_pub public key representing the merge capability + * @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] 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 + * @return transaction status code + */ enum GNUNET_DB_QueryStatus - (*insert_purse_deposit)( + (*select_purse_by_merge_pub)( + void *cls, + const struct TALER_PurseMergePublicKeyP *merge_pub, + struct TALER_PurseContractPublicKeyP *purse_pub, + struct GNUNET_TIME_Timestamp *purse_expiration, + struct TALER_PrivateContractHashP *h_contract_terms, + struct TALER_Amount *target_amount, + struct TALER_Amount *balance, + struct TALER_PurseContractSignatureP *purse_sig); + + + /** + * Function called to execute a transaction crediting + * a purse with @a amount from @a coin_pub. Reduces the + * value of @a coin_pub and increase the balance of + * the @a purse_pub purse. If the balance reaches the + * target amount and the purse has been merged, triggers + * the updates of the reserve/account balance. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub purse to credit + * @param coin_pub coin to deposit (debit) + * @param amount fraction of the coin's value to deposit + * @param coin_sig signature affirming the operation + * @return transaction status code + */ + enum GNUNET_DB_QueryStatus + (*do_purse_deposit)( void *cls, const struct TALER_PurseContractPublicKeyP *purse_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub, @@ -4413,53 +4516,99 @@ struct TALER_EXCHANGEDB_Plugin const struct TALER_CoinSpendSignatureP *coin_sig); + /** + * Function called to approve merging a purse into a + * reserve by the respective purse merge key. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub purse to merge + * @param merge_sig signature affirming the merge + * @param merge_timestamp time of the merge + * @param partner_url URL of the partner exchange, can be NULL if the reserves lives with us + * @param reserve_pub public key of the reserve to credit + * @return transaction status code + */ enum GNUNET_DB_QueryStatus - (*insert_purse_merge)( + (*do_purse_merge)( void *cls, const struct TALER_PurseContractPublicKeyP *purse_pub, - const struct TALER_PurseMergePublicKeyP *merge_pub, const struct TALER_PurseMergeSignatureP *merge_sig, const struct GNUNET_TIME_Timestamp merge_timestamp, - uint64_t partner_serial_id, + const char *partner_url, const struct TALER_ReservePublicKeyP *reserve_pub); + /** + * Function called to approve merging of a purse with + * an account, made by the receiving account. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub public key of the purse + * @param[out] merge_sig set to the signature confirming the merge + * @param[out] merge_timestamp set to the time of the merge + * @param[out] partner_url set to the URL of the target exchange, or NULL if the target exchange is us. To be freed by the caller. + * @param[out] reserve_pub set to the public key of the reserve/account being credited + * @return transaction status code + */ enum GNUNET_DB_QueryStatus (*select_purse_merge)( void *cls, const struct TALER_PurseContractPublicKeyP *purse_pub, - struct TALER_PurseMergePublicKeyP *merge_pub, struct TALER_PurseMergeSignatureP *merge_sig, struct GNUNET_TIME_Timestamp *merge_timestamp, - uint64_t *partner_serial_id, + char **partner_url, struct TALER_ReservePublicKeyP *reserve_pub); + /** + * Function called to approve merging of a purse with + * an account, made by the receiving account. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub public key of the purse being merged + * @param reserve_pub public key of the account being credited + * @param reserve_sig signature of the account holder affirming the merge + * @return transaction status code + */ enum GNUNET_DB_QueryStatus - (*insert_account_merge)( + (*do_account_merge)( void *cls, const struct TALER_PurseContractPublicKeyP *purse_pub, const struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_ReserveSignatureP *reserve_sig); - enum GNUNET_DB_QueryStatus - (*select_account_merge)( - void *cls, - const struct TALER_PurseContractPublicKeyP *purse_pub, - struct TALER_ReservePublicKeyP *reserve_pub, - struct TALER_ReserveSignatureP *reserve_sig); - - + /** + * Function called to persist a signature that + * prove that the client requested an + * account history. Debits the @a history_fee from + * the reserve (if possible). + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param reserve_pub account that the history was requested for + * @param reserve_sig signature affirming the request + * @param request_timestamp when was the request made + * @param history_fee how much should the @a reserve_pub be charged for the request + * @return transaction status code + */ enum GNUNET_DB_QueryStatus (*insert_history_request)( void *cls, const struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_ReserveSignatureP *reserve_sig, struct GNUNET_TIME_Absolute request_timestamp, - const struct TALER_Amount *history); + const struct TALER_Amount *history_fee); + /** + * Function called to initiate closure of an account. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param reserve_pub public key of the account to close + * @param reserve_sig signature affiming that the account is to be closed + * @param[out] final_balance set to the final balance in the account that will be wired back to the origin account + * @return transaction status code + */ enum GNUNET_DB_QueryStatus (*insert_close_request)(void *cls, const struct TALER_ReservePublicKeyP *reserve_pub,