-fix fieldnames, regenerated DBs

This commit is contained in:
Christian Grothoff 2022-04-24 20:49:11 +02:00
parent b671d6b25d
commit b4965db0d2
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
15 changed files with 2578 additions and 2261 deletions

@ -1 +1 @@
Subproject commit bffe32411e8ded537c5615ea054b43b3f7334bcd Subproject commit fbd5974fba30cab15ef1b7454a5a609286c71508

View File

@ -1 +1 @@
1650014542 1650825040

View File

@ -113,7 +113,7 @@ currency = TESTKUDOS
[merchant-exchange-default] [merchant-exchange-default]
CURRENCY = TESTKUDOS CURRENCY = TESTKUDOS
EXCHANGE_BASE_URL = http://localhost:8081/ EXCHANGE_BASE_URL = http://localhost:8081/
MASTER_KEY = SDXD4H9RYCX8GNPZG73KB21JB9QMSWHK6857SZNMTW0K159WFTRG MASTER_KEY = C0KWBDJJ5Y0HQ5T0N5BXEDWWV10GM6GSQM8MN7M8B84QDRZDZ8QG
[merchant-account-merchant] [merchant-account-merchant]
ACTIVE_default = YES ACTIVE_default = YES
@ -157,7 +157,7 @@ CONFIG = postgres:///auditor-basedb
[exchange] [exchange]
LOOKAHEAD_SIGN = 32 weeks 1 day LOOKAHEAD_SIGN = 32 weeks 1 day
SIGNKEY_DURATION = 4 weeks SIGNKEY_DURATION = 4 weeks
MASTER_PUBLIC_KEY = SDXD4H9RYCX8GNPZG73KB21JB9QMSWHK6857SZNMTW0K159WFTRG MASTER_PUBLIC_KEY = C0KWBDJJ5Y0HQ5T0N5BXEDWWV10GM6GSQM8MN7M8B84QDRZDZ8QG
SIGNKEY_LEGAL_DURATION = 4 weeks SIGNKEY_LEGAL_DURATION = 4 weeks
UNIXPATH = ${TALER_RUNTIME_DIR}/exchange.http UNIXPATH = ${TALER_RUNTIME_DIR}/exchange.http
@ -175,7 +175,7 @@ DATABASE = postgres:///auditor-basedb
CONFIG = postgres:///auditor-basedb CONFIG = postgres:///auditor-basedb
[auditor] [auditor]
PUBLIC_KEY = 7Z4C34S3G88KNDSEG9HF7HN6CAH5GNKES4KV8F2JKYV2CBPV4AG0 PUBLIC_KEY = NW60794YCXWFWJFKD7HK3GAQFNBH78T40BMQPTQP1XG9ZETH25SG
TINY_AMOUNT = TESTKUDOS:0.01 TINY_AMOUNT = TESTKUDOS:0.01
BASE_URL = http://localhost:8083/ BASE_URL = http://localhost:8083/

View File

@ -1 +1 @@
SDXD4H9RYCX8GNPZG73KB21JB9QMSWHK6857SZNMTW0K159WFTRG C0KWBDJJ5Y0HQ5T0N5BXEDWWV10GM6GSQM8MN7M8B84QDRZDZ8QG

File diff suppressed because it is too large Load Diff

View File

@ -186,7 +186,6 @@ for n in `seq 1 2`
do do
echo -n "." echo -n "."
OK=0 OK=0
# bank
wget --timeout=1 http://localhost:8081/keys -o /dev/null -O /dev/null >/dev/null || continue wget --timeout=1 http://localhost:8081/keys -o /dev/null -O /dev/null >/dev/null || continue
OK=1 OK=1
break break
@ -197,6 +196,9 @@ then
exit_skip "Failed to setup keys" exit_skip "Failed to setup keys"
fi fi
echo " DONE"
echo -n "Adding auditor signatures ..."
taler-auditor-offline -c $CONF \ taler-auditor-offline -c $CONF \
download sign upload &> taler-auditor-offline.log download sign upload &> taler-auditor-offline.log

View File

@ -1 +1 @@
1650014960 1650825413

View File

@ -1 +1 @@
7VE6NGN2VG8623EW517VSC713RG14S9MCY95AB59S2W4QCEJGR5G 05TD8T49D8A9NXQ126MRBW5KQAR73RDBB4QC3QH14TZ0T9P8W4CG

File diff suppressed because it is too large Load Diff

View File

@ -45,6 +45,11 @@ struct ReservePurseContext
*/ */
const struct TALER_ReservePublicKeyP *reserve_pub; const struct TALER_ReservePublicKeyP *reserve_pub;
/**
* Fees for the operation.
*/
const struct TEH_GlobalFee *gf;
/** /**
* Signature of the reserve affirming the merge. * Signature of the reserve affirming the merge.
*/ */
@ -194,8 +199,9 @@ purse_transaction (void *cls,
{ {
struct ReservePurseContext *rpc = cls; struct ReservePurseContext *rpc = cls;
enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs;
bool in_conflict = true;
{
bool in_conflict = true;
/* 1) store purse */ /* 1) store purse */
qs = TEH_plugin->insert_purse_request (TEH_plugin->cls, qs = TEH_plugin->insert_purse_request (TEH_plugin->cls,
&rpc->purse_pub, &rpc->purse_pub,
@ -241,7 +247,7 @@ purse_transaction (void *cls,
&target_amount, &target_amount,
&balance, &balance,
&purse_sig); &purse_sig);
if (qs < 0) if (qs <= 0)
{ {
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs);
TALER_LOG_WARNING ("Failed to fetch purse information from database\n"); TALER_LOG_WARNING ("Failed to fetch purse information from database\n");
@ -256,7 +262,7 @@ purse_transaction (void *cls,
connection, connection,
MHD_HTTP_CONFLICT, MHD_HTTP_CONFLICT,
TALER_JSON_pack_ec ( TALER_JSON_pack_ec (
TALER_EC_EXCHANGE_PURSE_CREATE_CONFLICTING_META_DATA), TALER_EC_EXCHANGE_RESERVES_PURSE_CREATE_CONFLICTING_META_DATA),
TALER_JSON_pack_amount ("amount", TALER_JSON_pack_amount ("amount",
&target_amount), &target_amount),
GNUNET_JSON_pack_uint64 ("min_age", GNUNET_JSON_pack_uint64 ("min_age",
@ -271,12 +277,98 @@ purse_transaction (void *cls,
&merge_pub)); &merge_pub));
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
} }
}
/* 2) FIXME: merge purse with reserve (and debit reserve for purse creation!) */ /* 2) create purse with reserve (and debit reserve for purse creation!) */
{
bool in_conflict = true;
bool insufficient_funds = true;
qs = TEH_plugin->do_reserve_purse (TEH_plugin->cls,
&rpc->purse_pub,
&rpc->merge_sig,
rpc->merge_timestamp,
&rpc->reserve_sig,
&rpc->gf->fees.purse,
rpc->reserve_pub,
&in_conflict,
&insufficient_funds);
if (qs < 0)
{
if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
return qs;
TALER_LOG_WARNING (
"Failed to store purse merge information in database\n");
*mhd_ret =
TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_STORE_FAILED,
"do reserve purse");
return qs;
}
if (in_conflict)
{
/* same purse already merged into a different reserve!? */
struct TALER_PurseContractPublicKeyP purse_pub;
struct TALER_PurseMergeSignatureP merge_sig;
struct GNUNET_TIME_Timestamp merge_timestamp;
char *partner_url;
struct TALER_ReservePublicKeyP reserve_pub;
TEH_plugin->rollback (TEH_plugin->cls);
qs = TEH_plugin->select_purse_merge (
TEH_plugin->cls,
&purse_pub,
&merge_sig,
&merge_timestamp,
&partner_url,
&reserve_pub);
if (qs <= 0)
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs);
TALER_LOG_WARNING (
"Failed to fetch purse merge information from database\n");
*mhd_ret = TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
"select purse merge");
return GNUNET_DB_STATUS_HARD_ERROR;
}
*mhd_ret
= TALER_MHD_REPLY_JSON_PACK (
connection,
MHD_HTTP_CONFLICT,
TALER_JSON_pack_ec (
TALER_EC_EXCHANGE_RESERVES_PURSE_MERGE_CONFLICTING_META_DATA),
GNUNET_JSON_pack_string ("partner_url",
NULL == partner_url
? TEH_base_url
: partner_url),
GNUNET_JSON_pack_timestamp ("merge_timestamp",
merge_timestamp),
GNUNET_JSON_pack_data_auto ("merge_sig",
&merge_sig),
GNUNET_JSON_pack_data_auto ("reserve_pub",
&reserve_pub));
GNUNET_free (partner_url);
return GNUNET_DB_STATUS_HARD_ERROR;
}
if (insufficient_funds)
{
*mhd_ret
= TALER_MHD_REPLY_JSON_PACK (
connection,
MHD_HTTP_CONFLICT,
TALER_JSON_pack_ec (
TALER_EC_EXCHANGE_RESERVES_PURSE_CREATE_INSUFFICIENT_FUNDS));
return GNUNET_DB_STATUS_HARD_ERROR;
}
}
/* 3) if present, persist contract */ /* 3) if present, persist contract */
in_conflict = true; if (NULL != rpc->econtract)
{
bool in_conflict = true;
qs = TEH_plugin->insert_contract (TEH_plugin->cls, qs = TEH_plugin->insert_contract (TEH_plugin->cls,
&rpc->purse_pub, &rpc->purse_pub,
&rpc->contract_pub, &rpc->contract_pub,
@ -338,7 +430,7 @@ purse_transaction (void *cls,
&pub_ckey)); &pub_ckey));
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
} }
}
return qs; return qs;
} }
@ -391,7 +483,6 @@ TEH_handler_reserves_purse (
&rpc.purse_expiration), &rpc.purse_expiration),
GNUNET_JSON_spec_end () GNUNET_JSON_spec_end ()
}; };
const struct TEH_GlobalFee *gf;
{ {
enum GNUNET_GenericReturnValue res; enum GNUNET_GenericReturnValue res;
@ -433,9 +524,9 @@ TEH_handler_reserves_purse (
TALER_EC_EXCHANGE_RESERVES_PURSE_EXPIRATION_IS_NEVER, TALER_EC_EXCHANGE_RESERVES_PURSE_EXPIRATION_IS_NEVER,
NULL); NULL);
} }
gf = TEH_keys_global_fee_by_time (TEH_keys_get_state (), rpc.gf = TEH_keys_global_fee_by_time (TEH_keys_get_state (),
rpc.exchange_timestamp); rpc.exchange_timestamp);
if (NULL == gf) if (NULL == rpc.gf)
{ {
GNUNET_log (GNUNET_ERROR_TYPE_WARNING, GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Cannot purse purse: global fees not configured!\n"); "Cannot purse purse: global fees not configured!\n");

View File

@ -2710,6 +2710,27 @@ END $$;
-- IS 'Checks that the partner exists, the purse has not been merged with a different reserve and that the purse is full. If so, persists the merge data. Caller MUST abort the transaction on failures so as to not persist data by accident.'; -- IS 'Checks that the partner exists, the purse has not been merged with a different reserve and that the purse is full. If so, persists the merge data. Caller MUST abort the transaction on failures so as to not persist data by accident.';
CREATE OR REPLACE FUNCTION exchange_do_reserve_purse(
IN in_purse_pub BYTEA,
IN in_merge_sig BYTEA,
IN in_merge_timestamp INT8,
IN in_reserve_sig BYTEA,
IN in_purse_fee_val INT8,
IN in_purse_fee_frac INT8,
IN in_reserve_pub BYTEA,
OUT out_no_funds BOOLEAN,
OUT out_conflict BOOLEAN)
LANGUAGE plpgsql
AS $$
BEGIN
-- FIXME: implement!
out_conflict=TRUE;
out_no_funds=TRUE;
END $$;
CREATE OR REPLACE FUNCTION exchange_do_account_merge( CREATE OR REPLACE FUNCTION exchange_do_account_merge(
IN in_purse_pub BYTEA, IN in_purse_pub BYTEA,
IN in_reserve_pub BYTEA, IN in_reserve_pub BYTEA,

View File

@ -3525,6 +3525,15 @@ prepare_statements (struct PostgresClosure *pg)
" FROM exchange_do_purse_merge" " FROM exchange_do_purse_merge"
" ($1, $2, $3, $4, $5, $6);", " ($1, $2, $3, $4, $5, $6);",
6), 6),
/* Used in #postgres_do_reserve_purse() */
GNUNET_PQ_make_prepare (
"call_reserve_purse",
"SELECT"
" out_no_funds AS insufficient_funds"
",out_conflict AS conflict"
" FROM exchange_do_reserve_purse"
" ($1, $2, $3, $4, $5, $6, $7);",
7),
/* Used in #postgres_select_purse_merge */ /* Used in #postgres_select_purse_merge */
GNUNET_PQ_make_prepare ( GNUNET_PQ_make_prepare (
"select_purse_merge", "select_purse_merge",
@ -13561,6 +13570,59 @@ postgres_do_purse_merge (
} }
/**
* Function called insert request to merge a purse into a reserve by the
* respective purse merge key. The purse must not have been merged into a
* different reserve.
*
* @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 reserve_sig signature of the reserve affirming the merge
* @param purse_fee amount to charge the reserve for the purse creation
* @param reserve_pub public key of the reserve to credit
* @param[out] in_conflict set to true if @a purse_pub was merged into a different reserve already
* @param[out] insufficient_funds set to true if @a reserve_pub has insufficient capacity to create another purse
* @return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_do_reserve_purse (
void *cls,
const struct TALER_PurseContractPublicKeyP *purse_pub,
const struct TALER_PurseMergeSignatureP *merge_sig,
const struct GNUNET_TIME_Timestamp merge_timestamp,
const struct TALER_ReserveSignatureP *reserve_sig,
const struct TALER_Amount *purse_fee,
const struct TALER_ReservePublicKeyP *reserve_pub,
bool *in_conflict,
bool *insufficient_funds)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_auto_from_type (purse_pub),
GNUNET_PQ_query_param_auto_from_type (merge_sig),
GNUNET_PQ_query_param_timestamp (&merge_timestamp),
GNUNET_PQ_query_param_auto_from_type (reserve_sig),
TALER_PQ_query_param_amount (purse_fee),
GNUNET_PQ_query_param_auto_from_type (reserve_pub),
GNUNET_PQ_query_param_end
};
struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_bool ("insufficient_funds",
insufficient_funds),
GNUNET_PQ_result_spec_bool ("conflict",
in_conflict),
GNUNET_PQ_result_spec_end
};
return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"call_reserve_purse",
params,
rs);
}
/** /**
* Function called to approve merging of a purse with * Function called to approve merging of a purse with
* an account, made by the receiving account. * an account, made by the receiving account.
@ -13967,6 +14029,8 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
= &postgres_get_purse_deposit; = &postgres_get_purse_deposit;
plugin->do_purse_merge plugin->do_purse_merge
= &postgres_do_purse_merge; = &postgres_do_purse_merge;
plugin->do_reserve_purse
= &postgres_do_reserve_purse;
plugin->select_purse_merge plugin->select_purse_merge
= &postgres_select_purse_merge; = &postgres_select_purse_merge;
plugin->do_account_merge plugin->do_account_merge

View File

@ -4689,6 +4689,35 @@ struct TALER_EXCHANGEDB_Plugin
bool *in_conflict); bool *in_conflict);
/**
* Function called insert request to merge a purse into a reserve by the
* respective purse merge key. The purse must not have been merged into a
* different reserve.
*
* @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 reserve_sig signature of the reserve affirming the merge
* @param purse_fee amount to charge the reserve for the purse creation
* @param reserve_pub public key of the reserve to credit
* @param[out] in_conflict set to true if @a purse_pub was merged into a different reserve already
* @param[out] insufficient_funds set to true if @a reserve_pub has insufficient capacity to create another purse
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
(*do_reserve_purse)(
void *cls,
const struct TALER_PurseContractPublicKeyP *purse_pub,
const struct TALER_PurseMergeSignatureP *merge_sig,
const struct GNUNET_TIME_Timestamp merge_timestamp,
const struct TALER_ReserveSignatureP *reserve_sig,
const struct TALER_Amount *purse_fee,
const struct TALER_ReservePublicKeyP *reserve_pub,
bool *in_conflict,
bool *insufficient_funds);
/** /**
* Function called to approve merging of a purse with * Function called to approve merging of a purse with
* an account, made by the receiving account. * an account, made by the receiving account.

View File

@ -521,13 +521,13 @@ parse_global_fee (struct TALER_EXCHANGE_GlobalFee *gf,
const struct TALER_EXCHANGE_Keys *key_data) const struct TALER_EXCHANGE_Keys *key_data)
{ {
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_timestamp ("start_time", GNUNET_JSON_spec_timestamp ("start_date",
&gf->start_date), &gf->start_date),
GNUNET_JSON_spec_timestamp ("end_time", GNUNET_JSON_spec_timestamp ("end_date",
&gf->end_date), &gf->end_date),
GNUNET_JSON_spec_relative_time ("purse_timeout", GNUNET_JSON_spec_relative_time ("purse_timeout",
&gf->purse_timeout), &gf->purse_timeout),
GNUNET_JSON_spec_relative_time ("kyc_timeout", GNUNET_JSON_spec_relative_time ("account_kyc_timeout",
&gf->kyc_timeout), &gf->kyc_timeout),
GNUNET_JSON_spec_relative_time ("history_expiration", GNUNET_JSON_spec_relative_time ("history_expiration",
&gf->history_expiration), &gf->history_expiration),

View File

@ -294,7 +294,6 @@ TALER_EXCHANGE_purse_create_with_merge (
&contract_pub.ecdhe_pub); &contract_pub.ecdhe_pub);
{ {
// FIXME: get purse expiration time from contract?
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
TALER_JSON_spec_amount_any ("amount", TALER_JSON_spec_amount_any ("amount",
&pcm->purse_value_after_fees), &pcm->purse_value_after_fees),
@ -302,8 +301,7 @@ TALER_EXCHANGE_purse_create_with_merge (
GNUNET_JSON_spec_uint32 ("minimum_age", GNUNET_JSON_spec_uint32 ("minimum_age",
&min_age), &min_age),
NULL), NULL),
// FIXME: correct field name? GNUNET_JSON_spec_timestamp ("pay_deadline",
GNUNET_JSON_spec_timestamp ("payment_deadline",
&pcm->purse_expiration), &pcm->purse_expiration),
GNUNET_JSON_spec_end () GNUNET_JSON_spec_end ()
}; };