-misc fixes to reserve history

This commit is contained in:
Christian Grothoff 2022-05-23 14:57:00 +02:00
parent 2035294adb
commit cdd2930a99
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
13 changed files with 93 additions and 28 deletions

View File

@ -53,6 +53,11 @@ struct ReserveStatusContext
*/ */
struct TALER_EXCHANGEDB_ReserveHistory *rh; struct TALER_EXCHANGEDB_ReserveHistory *rh;
/**
* Current KYC status.
*/
struct TALER_EXCHANGEDB_KycStatus kyc;
/** /**
* Current reserve balance. * Current reserve balance.
*/ */
@ -85,6 +90,8 @@ reply_reserve_status_success (struct MHD_Connection *connection,
MHD_HTTP_OK, MHD_HTTP_OK,
TALER_JSON_pack_amount ("balance", TALER_JSON_pack_amount ("balance",
&rhc->balance), &rhc->balance),
GNUNET_JSON_pack_bool ("kyc_passed",
rhc->kyc.ok),
GNUNET_JSON_pack_array_steal ("history", GNUNET_JSON_pack_array_steal ("history",
json_history)); json_history));
} }
@ -114,6 +121,20 @@ reserve_status_transaction (void *cls,
struct ReserveStatusContext *rsc = cls; struct ReserveStatusContext *rsc = cls;
enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs;
qs = TEH_plugin->inselect_wallet_kyc_status (TEH_plugin->cls,
rsc->reserve_pub,
&rsc->kyc);
if (qs < 0)
{
if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
return qs;
GNUNET_break (0);
*mhd_ret = TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
"inselect_wallet_status");
return qs;
}
qs = TEH_plugin->get_reserve_history (TEH_plugin->cls, qs = TEH_plugin->get_reserve_history (TEH_plugin->cls,
rsc->reserve_pub, rsc->reserve_pub,
&rsc->balance, &rsc->balance,

View File

@ -741,7 +741,7 @@ TEH_RESPONSE_compile_reserve_history (
pos->details.merge; pos->details.merge;
struct TALER_Amount amount; struct TALER_Amount amount;
GNUNET_assert (0 >= GNUNET_assert (0 <=
TALER_amount_subtract (&amount, TALER_amount_subtract (&amount,
&merge->amount_with_fee, &merge->amount_with_fee,
&merge->purse_fee)); &merge->purse_fee));

View File

@ -77,6 +77,7 @@ common_free_reserve_history (void *cls,
merge = rh->details.merge; merge = rh->details.merge;
GNUNET_free (merge); GNUNET_free (merge);
break;
} }
case TALER_EXCHANGEDB_RO_HISTORY_REQUEST: case TALER_EXCHANGEDB_RO_HISTORY_REQUEST:
{ {
@ -84,6 +85,7 @@ common_free_reserve_history (void *cls,
history = rh->details.history; history = rh->details.history;
GNUNET_free (history); GNUNET_free (history);
break;
} }
} }
{ {

View File

@ -4909,7 +4909,7 @@ postgres_inselect_wallet_kyc_status (
payto_uri, payto_uri,
&h_payto, &h_payto,
kyc); kyc);
GNUNET_log (GNUNET_ERROR_TYPE_WARNING, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Wire account for `%s' is %llu\n", "Wire account for `%s' is %llu\n",
payto_uri, payto_uri,
(unsigned long long) kyc->payment_target_uuid); (unsigned long long) kyc->payment_target_uuid);
@ -6230,8 +6230,8 @@ add_p2p_merge (void *cls,
merge->flags = (enum TALER_WalletAccountMergeFlags) flags32; merge->flags = (enum TALER_WalletAccountMergeFlags) flags32;
} }
GNUNET_assert (0 <= GNUNET_assert (0 <=
TALER_amount_add (&rhc->balance_out, TALER_amount_add (&rhc->balance_in,
&rhc->balance_out, &rhc->balance_in,
&merge->amount_with_fee)); &merge->amount_with_fee));
GNUNET_assert (0 <= GNUNET_assert (0 <=
TALER_amount_subtract (&rhc->balance_out, TALER_amount_subtract (&rhc->balance_out,
@ -6443,6 +6443,12 @@ postgres_get_reserve_status (void *cls,
/** #TALER_EXCHANGEDB_RO_EXCHANGE_TO_BANK */ /** #TALER_EXCHANGEDB_RO_EXCHANGE_TO_BANK */
{ "close_by_reserve", { "close_by_reserve",
&add_exchange_to_bank }, &add_exchange_to_bank },
/** #TALER_EXCHANGEDB_RO_PURSE_MERGE */
{ "merge_by_reserve",
&add_p2p_merge },
/** #TALER_EXCHANGEDB_RO_HISTORY_REQUEST */
{ "history_by_reserve",
&add_history_requests },
/* List terminator */ /* List terminator */
{ NULL, { NULL,
NULL } NULL }

View File

@ -1696,11 +1696,6 @@ struct TALER_EXCHANGE_ReserveStatus
*/ */
bool kyc_ok; bool kyc_ok;
/**
* KYC required to withdraw?
*/
bool kyc_required;
} ok; } ok;
} details; } details;

View File

@ -415,6 +415,8 @@ parse_merge (struct TALER_EXCHANGE_ReserveHistoryEntry *rh,
&rh->details.merge_details.purse_fee), &rh->details.merge_details.purse_fee),
GNUNET_JSON_spec_timestamp ("merge_timestamp", GNUNET_JSON_spec_timestamp ("merge_timestamp",
&rh->details.merge_details.merge_timestamp), &rh->details.merge_details.merge_timestamp),
GNUNET_JSON_spec_timestamp ("purse_expiration",
&rh->details.merge_details.purse_expiration),
GNUNET_JSON_spec_end () GNUNET_JSON_spec_end ()
}; };

View File

@ -100,8 +100,6 @@ handle_reserves_status_ok (struct TALER_EXCHANGE_ReservesStatusHandle *rsh,
&rs.details.ok.balance), &rs.details.ok.balance),
GNUNET_JSON_spec_bool ("kyc_passed", GNUNET_JSON_spec_bool ("kyc_passed",
&rs.details.ok.kyc_ok), &rs.details.ok.kyc_ok),
GNUNET_JSON_spec_bool ("kyc_required",
&rs.details.ok.kyc_required),
GNUNET_JSON_spec_json ("history", GNUNET_JSON_spec_json ("history",
&history), &history),
GNUNET_JSON_spec_end () GNUNET_JSON_spec_end ()

View File

@ -197,14 +197,12 @@ run (void *cls,
"create-reserve-1", "create-reserve-1",
"EUR:1", "EUR:1",
MHD_HTTP_OK), MHD_HTTP_OK),
#if FIXME
/* POST history doesn't yet support P2P transfers */ /* POST history doesn't yet support P2P transfers */
TALER_TESTING_cmd_reserves_status ( TALER_TESTING_cmd_reserve_status (
"push-check-post-merge-reserve-balance-post", "push-check-post-merge-reserve-balance-post",
"create-reserve-1", "create-reserve-1",
"EUR:1", "EUR:1",
MHD_HTTP_OK), MHD_HTTP_OK),
#endif
/* Test conflicting merge */ /* Test conflicting merge */
TALER_TESTING_cmd_purse_merge ( TALER_TESTING_cmd_purse_merge (
"purse-merge-into-reserve", "purse-merge-into-reserve",
@ -374,8 +372,6 @@ run (void *cls,
"payto://x-taler-bank/localhost/2", "payto://x-taler-bank/localhost/2",
MHD_HTTP_NO_CONTENT, MHD_HTTP_NO_CONTENT,
false), false),
TALER_TESTING_cmd_exec_offline_sign_keys ("offline-sign-future-keys",
config_file),
TALER_TESTING_cmd_exec_offline_sign_fees ("offline-sign-wire-fees", TALER_TESTING_cmd_exec_offline_sign_fees ("offline-sign-wire-fees",
config_file, config_file,
"EUR:0.01", "EUR:0.01",
@ -391,6 +387,8 @@ run (void *cls,
GNUNET_TIME_UNIT_MINUTES, GNUNET_TIME_UNIT_MINUTES,
GNUNET_TIME_UNIT_DAYS, GNUNET_TIME_UNIT_DAYS,
1), 1),
TALER_TESTING_cmd_exec_offline_sign_keys ("offline-sign-future-keys",
config_file),
TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys", TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys",
1), 1),
TALER_TESTING_cmd_batch ("withdraw", TALER_TESTING_cmd_batch ("withdraw",

View File

@ -72,6 +72,12 @@ struct PurseDepositState
*/ */
struct TALER_PurseContractPublicKeyP purse_pub; struct TALER_PurseContractPublicKeyP purse_pub;
/**
* The reserve we are being deposited into.
* Set as a trait once we know the reserve.
*/
struct TALER_ReservePublicKeyP reserve_pub;
/** /**
* PurseDeposit handle while operation is running. * PurseDeposit handle while operation is running.
*/ */
@ -151,6 +157,7 @@ deposit_cb (void *cls,
{ {
const struct TALER_TESTING_Command *purse_cmd; const struct TALER_TESTING_Command *purse_cmd;
const struct TALER_ReserveSignatureP *reserve_sig; const struct TALER_ReserveSignatureP *reserve_sig;
const struct TALER_ReservePublicKeyP *reserve_pub;
const struct GNUNET_TIME_Timestamp *merge_timestamp; const struct GNUNET_TIME_Timestamp *merge_timestamp;
purse_cmd = TALER_TESTING_interpreter_lookup_command (ds->is, purse_cmd = TALER_TESTING_interpreter_lookup_command (ds->is,
@ -164,6 +171,15 @@ deposit_cb (void *cls,
TALER_TESTING_interpreter_fail (ds->is); TALER_TESTING_interpreter_fail (ds->is);
return; return;
} }
if (GNUNET_OK !=
TALER_TESTING_get_trait_reserve_pub (purse_cmd,
&reserve_pub))
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (ds->is);
return;
}
ds->reserve_pub = *reserve_pub;
if (GNUNET_OK != if (GNUNET_OK !=
TALER_TESTING_get_trait_timestamp (purse_cmd, TALER_TESTING_get_trait_timestamp (purse_cmd,
0, 0,
@ -370,6 +386,7 @@ deposit_traits (void *cls,
struct TALER_TESTING_Trait traits[] = { struct TALER_TESTING_Trait traits[] = {
/* history entry MUST be first due to response code logic below! */ /* history entry MUST be first due to response code logic below! */
TALER_TESTING_make_trait_reserve_history (&ds->reserve_history), TALER_TESTING_make_trait_reserve_history (&ds->reserve_history),
TALER_TESTING_make_trait_reserve_pub (&ds->reserve_pub),
TALER_TESTING_make_trait_purse_pub (&ds->purse_pub), TALER_TESTING_make_trait_purse_pub (&ds->purse_pub),
TALER_TESTING_trait_end () TALER_TESTING_trait_end ()
}; };

View File

@ -131,21 +131,16 @@ merge_cb (void *cls,
ds->dh = NULL; ds->dh = NULL;
if (MHD_HTTP_OK == dr->hr.http_status) if (MHD_HTTP_OK == dr->hr.http_status)
{ {
const struct TALER_EXCHANGE_Keys *keys;
const struct TALER_EXCHANGE_GlobalFee *gf;
ds->reserve_history.type = TALER_EXCHANGE_RTT_MERGE; ds->reserve_history.type = TALER_EXCHANGE_RTT_MERGE;
keys = TALER_EXCHANGE_get_keys (ds->is->exchange);
GNUNET_assert (NULL != keys);
gf = TALER_EXCHANGE_get_global_fee (keys,
ds->merge_timestamp);
GNUNET_assert (NULL != gf);
ds->reserve_history.amount = ds->value_after_fees; ds->reserve_history.amount = ds->value_after_fees;
ds->reserve_history.details.merge_details.purse_fee = gf->fees.purse; TALER_amount_set_zero (ds->value_after_fees.currency,
&ds->reserve_history.details.merge_details.purse_fee);
ds->reserve_history.details.merge_details.h_contract_terms ds->reserve_history.details.merge_details.h_contract_terms
= ds->h_contract_terms; = ds->h_contract_terms;
ds->reserve_history.details.merge_details.merge_pub ds->reserve_history.details.merge_details.merge_pub
= ds->merge_pub; = ds->merge_pub;
ds->reserve_history.details.merge_details.purse_pub
= ds->purse_pub;
ds->reserve_history.details.merge_details.reserve_sig ds->reserve_history.details.merge_details.reserve_sig
= *dr->reserve_sig; = *dr->reserve_sig;
ds->reserve_history.details.merge_details.merge_timestamp ds->reserve_history.details.merge_details.merge_timestamp
@ -356,6 +351,7 @@ merge_traits (void *cls,
struct TALER_TESTING_Trait traits[] = { struct TALER_TESTING_Trait traits[] = {
/* history entry MUST be first due to response code logic below! */ /* history entry MUST be first due to response code logic below! */
TALER_TESTING_make_trait_reserve_history (&ds->reserve_history), TALER_TESTING_make_trait_reserve_history (&ds->reserve_history),
TALER_TESTING_make_trait_reserve_pub (&ds->reserve_pub),
TALER_TESTING_make_trait_timestamp (0, TALER_TESTING_make_trait_timestamp (0,
&ds->merge_timestamp), &ds->merge_timestamp),
TALER_TESTING_trait_end () TALER_TESTING_trait_end ()

View File

@ -122,7 +122,12 @@ analyze_command (const struct TALER_ReservePublicKeyP *reserve_pub,
history_length, history_length,
history, history,
found)) found))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Entry for batch step `%s' missing in history\n",
step->label);
return GNUNET_SYSERR; return GNUNET_SYSERR;
}
} }
return GNUNET_OK; return GNUNET_OK;
} }
@ -251,6 +256,9 @@ reserve_history_cb (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Entry for command `%s' missing in history\n", "Entry for command `%s' missing in history\n",
cmd->label); cmd->label);
json_dumpf (rs->hr.reply,
stderr,
JSON_INDENT (2));
TALER_TESTING_interpreter_fail (ss->is); TALER_TESTING_interpreter_fail (ss->is);
return; return;
} }
@ -262,6 +270,9 @@ reserve_history_cb (void *cls,
"History entry at index %u of type %d not justified by command history\n", "History entry at index %u of type %d not justified by command history\n",
i, i,
rs->details.ok.history[i].type); rs->details.ok.history[i].type);
json_dumpf (rs->hr.reply,
stderr,
JSON_INDENT (2));
TALER_TESTING_interpreter_fail (ss->is); TALER_TESTING_interpreter_fail (ss->is);
return; return;
} }

View File

@ -46,6 +46,11 @@ struct ReservePurseState
*/ */
struct TALER_ReservePrivateKeyP reserve_priv; struct TALER_ReservePrivateKeyP reserve_priv;
/**
* Reserve public key.
*/
struct TALER_ReservePublicKeyP reserve_pub;
/** /**
* Reserve signature generated for the request * Reserve signature generated for the request
* (client-side). * (client-side).
@ -176,6 +181,8 @@ purse_run (void *cls,
GNUNET_CRYPTO_eddsa_key_create (&ds->purse_priv.eddsa_priv); GNUNET_CRYPTO_eddsa_key_create (&ds->purse_priv.eddsa_priv);
GNUNET_CRYPTO_eddsa_key_get_public (&ds->purse_priv.eddsa_priv, GNUNET_CRYPTO_eddsa_key_get_public (&ds->purse_priv.eddsa_priv,
&ds->purse_pub.eddsa_pub); &ds->purse_pub.eddsa_pub);
GNUNET_CRYPTO_eddsa_key_get_public (&ds->reserve_priv.eddsa_priv,
&ds->reserve_pub.eddsa_pub);
GNUNET_CRYPTO_eddsa_key_create (&ds->merge_priv.eddsa_priv); GNUNET_CRYPTO_eddsa_key_create (&ds->merge_priv.eddsa_priv);
GNUNET_CRYPTO_ecdhe_key_create (&ds->contract_priv.ecdhe_priv); GNUNET_CRYPTO_ecdhe_key_create (&ds->contract_priv.ecdhe_priv);
ds->purse_expiration = GNUNET_TIME_absolute_to_timestamp ( ds->purse_expiration = GNUNET_TIME_absolute_to_timestamp (
@ -261,6 +268,7 @@ purse_traits (void *cls,
TALER_TESTING_make_trait_merge_priv (&ds->merge_priv), TALER_TESTING_make_trait_merge_priv (&ds->merge_priv),
TALER_TESTING_make_trait_contract_priv (&ds->contract_priv), TALER_TESTING_make_trait_contract_priv (&ds->contract_priv),
TALER_TESTING_make_trait_reserve_priv (&ds->reserve_priv), TALER_TESTING_make_trait_reserve_priv (&ds->reserve_priv),
TALER_TESTING_make_trait_reserve_pub (&ds->reserve_pub),
TALER_TESTING_make_trait_reserve_sig (&ds->reserve_sig), TALER_TESTING_make_trait_reserve_sig (&ds->reserve_sig),
TALER_TESTING_trait_end () TALER_TESTING_trait_end ()
}; };

View File

@ -87,7 +87,7 @@ analyze_command (const struct TALER_ReservePublicKeyP *reserve_pub,
const struct TALER_TESTING_Command *cmd, const struct TALER_TESTING_Command *cmd,
unsigned int history_length, unsigned int history_length,
const struct TALER_EXCHANGE_ReserveHistoryEntry *history, const struct TALER_EXCHANGE_ReserveHistoryEntry *history,
int *found) bool *found)
{ {
if (TALER_TESTING_cmd_is_batch (cmd)) if (TALER_TESTING_cmd_is_batch (cmd))
{ {
@ -114,7 +114,12 @@ analyze_command (const struct TALER_ReservePublicKeyP *reserve_pub,
history_length, history_length,
history, history,
found)) found))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Entry for batch step `%s' missing in history\n",
step->label);
return GNUNET_SYSERR; return GNUNET_SYSERR;
}
} }
return GNUNET_OK; return GNUNET_OK;
} }
@ -186,7 +191,7 @@ reserve_status_cb (void *cls,
__LINE__); __LINE__);
json_dumpf (rs->hr.reply, json_dumpf (rs->hr.reply,
stderr, stderr,
0); JSON_INDENT (2));
TALER_TESTING_interpreter_fail (ss->is); TALER_TESTING_interpreter_fail (ss->is);
return; return;
} }
@ -209,7 +214,7 @@ reserve_status_cb (void *cls,
return; return;
} }
{ {
int found[rs->details.ok.history_len]; bool found[rs->details.ok.history_len];
memset (found, memset (found,
0, 0,
@ -228,6 +233,9 @@ reserve_status_cb (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Entry for command `%s' missing in history\n", "Entry for command `%s' missing in history\n",
cmd->label); cmd->label);
json_dumpf (rs->hr.reply,
stderr,
JSON_INDENT (2));
TALER_TESTING_interpreter_fail (ss->is); TALER_TESTING_interpreter_fail (ss->is);
return; return;
} }
@ -239,6 +247,9 @@ reserve_status_cb (void *cls,
"History entry at index %u of type %d not justified by command status\n", "History entry at index %u of type %d not justified by command status\n",
i, i,
rs->details.ok.history[i].type); rs->details.ok.history[i].type);
json_dumpf (rs->hr.reply,
stderr,
JSON_INDENT (2));
TALER_TESTING_interpreter_fail (ss->is); TALER_TESTING_interpreter_fail (ss->is);
return; return;
} }