WIP - testing fails - interrupted work

My attempts to get deposit work failed so far, weird errors (denom
signagure invalid).  Work got interrupted, state unknown, to be
continued
This commit is contained in:
Özgür Kesim 2022-02-12 17:46:59 +01:00
parent a2b9f090a3
commit bfc1c45bab
Signed by: oec
GPG Key ID: 3D76A56D79EDD9D7
8 changed files with 190 additions and 88 deletions

View File

@ -5764,6 +5764,8 @@ postgres_ensure_coin_known (void *cls,
struct PostgresClosure *pg = cls;
enum GNUNET_DB_QueryStatus qs;
bool existed;
bool is_denom_pub_hash_null = false;
bool is_age_hash_null = false;
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_auto_from_type (&coin->coin_pub),
GNUNET_PQ_query_param_auto_from_type (&coin->denom_pub_hash),
@ -5771,20 +5773,19 @@ postgres_ensure_coin_known (void *cls,
TALER_PQ_query_param_denom_sig (&coin->denom_sig),
GNUNET_PQ_query_param_end
};
bool is_null = false;
struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_bool ("existed",
&existed),
GNUNET_PQ_result_spec_uint64 ("known_coin_id",
known_coin_id),
GNUNET_PQ_result_spec_allow_null (
GNUNET_PQ_result_spec_auto_from_type ("age_hash",
age_hash),
&is_null),
GNUNET_PQ_result_spec_allow_null (
GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
denom_hash),
&is_null),
&is_denom_pub_hash_null),
GNUNET_PQ_result_spec_allow_null (
GNUNET_PQ_result_spec_auto_from_type ("age_hash",
age_hash),
&is_age_hash_null),
GNUNET_PQ_result_spec_end
};
@ -5808,7 +5809,16 @@ postgres_ensure_coin_known (void *cls,
return TALER_EXCHANGEDB_CKS_ADDED;
break; /* continued below */
}
if ( (! is_null) &&
if ( (! is_denom_pub_hash_null) &&
(0 != GNUNET_memcmp (&denom_hash->hash,
&coin->denom_pub_hash.hash)) )
{
GNUNET_break_op (0);
return TALER_EXCHANGEDB_CKS_DENOM_CONFLICT;
}
if ( (! is_age_hash_null) &&
(0 != GNUNET_memcmp (age_hash,
&coin->age_commitment_hash)) )
{
@ -5816,13 +5826,7 @@ postgres_ensure_coin_known (void *cls,
GNUNET_break_op (0);
return TALER_EXCHANGEDB_CKS_AGE_CONFLICT;
}
if ( (! is_null) &&
(0 != GNUNET_memcmp (denom_hash,
&coin->denom_pub_hash)) )
{
GNUNET_break_op (0);
return TALER_EXCHANGEDB_CKS_DENOM_CONFLICT;
}
return TALER_EXCHANGEDB_CKS_PRESENT;
}

View File

@ -780,6 +780,7 @@ TALER_EXCHANGE_wire_cancel (struct TALER_EXCHANGE_WireHandle *wh);
* @param h_extensions hash over the extensions
* @param h_denom_pub hash of the coin denomination's public key
* @param coin_priv coins private key
* @param age_commitment age commitment that went into the making of the coin, might be NULL
* @param wallet_timestamp timestamp when the contract was finalized, must not be too far in the future
* @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests)
* @param refund_deadline date until which the merchant can issue a refund to the customer via the exchange (can be zero if refunds are not allowed); must not be after the @a wire_deadline
@ -794,6 +795,7 @@ TALER_EXCHANGE_deposit_permission_sign (
const struct TALER_ExtensionContractHash *h_extensions,
const struct TALER_DenominationHash *h_denom_pub,
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
const struct TALER_AgeCommitment *age_commitment,
struct GNUNET_TIME_Timestamp wallet_timestamp,
const struct TALER_MerchantPublicKeyP *merchant_pub,
struct GNUNET_TIME_Timestamp refund_deadline,
@ -899,6 +901,7 @@ typedef void
* @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the exchange)
* @param extension_details extension-specific details about the deposit relevant to the exchange
* @param coin_pub coins public key
* @param age_commitment age commitment that went into the making of the coin, might be NULL
* @param denom_pub denomination key with which the coin is signed
* @param denom_sig exchanges unblinded signature of the coin
* @param timestamp timestamp when the contract was finalized, must match approximately the current time of the exchange
@ -921,6 +924,7 @@ TALER_EXCHANGE_deposit (
const struct TALER_PrivateContractHash *h_contract_terms,
const json_t *extension_details,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_AgeCommitment *age_commitment,
const struct TALER_DenominationSignature *denom_sig,
const struct TALER_DenominationPublicKey *denom_pub,
struct GNUNET_TIME_Timestamp timestamp,

View File

@ -2461,8 +2461,8 @@ TALER_TESTING_get_trait (const struct TALER_TESTING_Trait *traits,
*/
#define TALER_TESTING_SIMPLE_TRAITS(op) \
op (bank_row, const uint64_t) \
op (reserve_priv, const struct TALER_ReservePrivateKeyP) \
op (reserve_pub, const struct TALER_ReservePublicKeyP) \
op (reserve_priv, const struct TALER_ReservePrivateKeyP) \
op (reserve_pub, const struct TALER_ReservePublicKeyP) \
op (merchant_priv, const struct TALER_MerchantPrivateKeyP) \
op (merchant_pub, const struct TALER_MerchantPublicKeyP) \
op (merchant_sig, const struct TALER_MerchantSignatureP) \
@ -2475,8 +2475,8 @@ TALER_TESTING_get_trait (const struct TALER_TESTING_Trait *traits,
op (exchange_bank_account_url, const char *) \
op (taler_uri, const char *) \
op (payto_uri, const char *) \
op (kyc_url, const char *) \
op (web_url, const char *) \
op (kyc_url, const char *) \
op (web_url, const char *) \
op (row, const uint64_t) \
op (payment_target_uuid, const uint64_t) \
op (array_length, const unsigned int) \
@ -2501,6 +2501,8 @@ TALER_TESTING_get_trait (const struct TALER_TESTING_Trait *traits,
#define TALER_TESTING_INDEXED_TRAITS(op) \
op (denom_pub, const struct TALER_EXCHANGE_DenomPublicKey) \
op (denom_sig, const struct TALER_DenominationSignature) \
op (age_commitment, struct TALER_AgeCommitment) \
op (h_age_commitment, struct TALER_AgeCommitmentHash) \
op (coin_priv, const struct TALER_CoinSpendPrivateKeyP) \
op (coin_pub, const struct TALER_CoinSpendPublicKeyP) \
op (absolute_time, const struct GNUNET_TIME_Absolute) \

View File

@ -462,6 +462,7 @@ handle_deposit_finished (void *cls,
* @param h_wire hash of the merchants account details
* @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the exchange)
* @param coin_pub coins public key
* @param h_age_commitment coins hash of age commitment, might be NULL
* @param denom_sig exchanges unblinded signature of the coin
* @param denom_pub denomination key with which the coin is signed
* @param denom_pub_hash hash of @a denom_pub
@ -478,6 +479,7 @@ verify_signatures (const struct TALER_EXCHANGE_DenomPublicKey *dki,
const struct TALER_PrivateContractHash *h_contract_terms,
const struct TALER_ExtensionContractHash *ech,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_AgeCommitmentHash *ach,
const struct TALER_DenominationSignature *denom_sig,
const struct TALER_DenominationPublicKey *denom_pub,
const struct TALER_DenominationHash *denom_pub_hash,
@ -514,8 +516,12 @@ verify_signatures (const struct TALER_EXCHANGE_DenomPublicKey *dki,
.coin_pub = *coin_pub,
.denom_pub_hash = *denom_pub_hash,
.denom_sig = *denom_sig,
.age_commitment_hash = {{{0}}} /* FIXME-Oec */
.age_commitment_hash = {{{0}}}
};
if (NULL != ach)
{
coin_info.age_commitment_hash = *ach;
}
if (GNUNET_YES !=
TALER_test_coin_valid (&coin_info,
@ -549,6 +555,7 @@ TALER_EXCHANGE_deposit (
const struct TALER_PrivateContractHash *h_contract_terms,
const json_t *extension_details,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_AgeCommitment *age_commitment,
const struct TALER_DenominationSignature *denom_sig,
const struct TALER_DenominationPublicKey *denom_pub,
struct GNUNET_TIME_Timestamp timestamp,
@ -569,6 +576,7 @@ TALER_EXCHANGE_deposit (
struct TALER_DenominationHash denom_pub_hash;
struct TALER_Amount amount_without_fee;
struct TALER_ExtensionContractHash ech;
struct TALER_AgeCommitmentHash ach;
char arg_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2 + 32];
if (NULL != extension_details)
@ -599,11 +607,14 @@ TALER_EXCHANGE_deposit (
}
GNUNET_assert (GNUNET_YES ==
TEAH_handle_is_ready (exchange));
/* initialize h_wire */
TALER_merchant_wire_signature_hash (merchant_payto_uri,
wire_salt,
&h_wire);
key_state = TALER_EXCHANGE_get_keys (exchange);
dki = TALER_EXCHANGE_get_denomination_key (key_state,
denom_pub);
if (NULL == dki)
@ -612,6 +623,7 @@ TALER_EXCHANGE_deposit (
GNUNET_break_op (0);
return NULL;
}
if (0 >
TALER_amount_subtract (&amount_without_fee,
amount,
@ -621,8 +633,13 @@ TALER_EXCHANGE_deposit (
GNUNET_break_op (0);
return NULL;
}
TALER_denom_pub_hash (denom_pub,
&denom_pub_hash);
if (NULL != age_commitment)
TALER_age_commitment_hash (age_commitment, &ach);
if (GNUNET_OK !=
verify_signatures (dki,
amount,
@ -632,6 +649,7 @@ TALER_EXCHANGE_deposit (
? &ech
: NULL,
coin_pub,
(NULL != age_commitment) ? &ach : NULL,
denom_sig,
denom_pub,
&denom_pub_hash,

View File

@ -169,42 +169,6 @@ run (void *cls,
TALER_TESTING_cmd_end ()
};
/**
* Test withdrawal with age restriction. Success is expected, so it MUST be
* called _after_ TALER_TESTING_cmd_exec_offline_sign_extensions is called,
* i. e. age restriction is activated in the exchange!
*
* TODO: create a test that tries to withdraw coins with age restriction but
* (expectedly) fails because the exchange doesn't support age restriction
* yet.
*/
struct TALER_TESTING_Command withdraw_age[] = {
/**
* Move money to the exchange's bank account.
*/
CMD_TRANSFER_TO_EXCHANGE ("create-reserve-age",
"EUR:6.02"),
TALER_TESTING_cmd_check_bank_admin_transfer ("check-create-reserve-age",
"EUR:6.02",
bc.user42_payto,
bc.exchange_payto,
"create-reserve-age"),
/**
* Make a reserve exist, according to the previous
* transfer.
*/
CMD_EXEC_WIREWATCH ("wirewatch-age"),
/**
* Withdraw EUR:5.
*/
TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-age",
"create-reserve-age",
"EUR:5",
13,
MHD_HTTP_OK),
TALER_TESTING_cmd_end ()
};
struct TALER_TESTING_Command spend[] = {
/**
* Spend the coin.
@ -371,6 +335,61 @@ run (void *cls,
TALER_TESTING_cmd_end ()
};
/**
* Test withdrawal with age restriction. Success is expected, so it MUST be
* called _after_ TALER_TESTING_cmd_exec_offline_sign_extensions is called,
* i. e. age restriction is activated in the exchange!
*
* TODO: create a test that tries to withdraw coins with age restriction but
* (expectedly) fails because the exchange doesn't support age restriction
* yet.
*/
struct TALER_TESTING_Command withdraw_age[] = {
/**
* Move money to the exchange's bank account.
*/
CMD_TRANSFER_TO_EXCHANGE ("create-reserve-age",
"EUR:6.02"),
TALER_TESTING_cmd_check_bank_admin_transfer ("check-create-reserve-age",
"EUR:6.02",
bc.user42_payto,
bc.exchange_payto,
"create-reserve-age"),
/**
* Make a reserve exist, according to the previous
* transfer.
*/
CMD_EXEC_WIREWATCH ("wirewatch-age"),
/**
* Withdraw EUR:5.
*/
TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-age-1",
"create-reserve-age",
"EUR:5",
13,
MHD_HTTP_OK),
TALER_TESTING_cmd_end ()
};
struct TALER_TESTING_Command spend_age[] = {
/**
* Spend the coin.
*/
TALER_TESTING_cmd_deposit ("deposit-simple-age",
"withdraw-coin-age-1",
0,
bc.user42_payto,
"{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}",
GNUNET_TIME_UNIT_ZERO,
"EUR:5",
MHD_HTTP_OK),
TALER_TESTING_cmd_deposit_replay ("deposit-simple-replay-age",
"deposit-simple-age",
MHD_HTTP_OK),
TALER_TESTING_cmd_end ()
};
struct TALER_TESTING_Command track[] = {
/* Try resolving a deposit's WTID, as we never triggered
* execution of transactions, the answer should be that
@ -1002,12 +1021,14 @@ run (void *cls,
wire),
TALER_TESTING_cmd_batch ("withdraw",
withdraw),
TALER_TESTING_cmd_batch ("withdraw-age",
withdraw_age),
TALER_TESTING_cmd_batch ("spend",
spend),
TALER_TESTING_cmd_batch ("refresh",
refresh),
TALER_TESTING_cmd_batch ("withdraw-age",
withdraw_age),
TALER_TESTING_cmd_batch ("spend-age",
spend_age),
TALER_TESTING_cmd_batch ("track",
track),
TALER_TESTING_cmd_batch ("unaggregation",

View File

@ -287,6 +287,7 @@ deposit_run (void *cls,
const struct TALER_TESTING_Command *coin_cmd;
const struct TALER_CoinSpendPrivateKeyP *coin_priv;
struct TALER_CoinSpendPublicKeyP coin_pub;
struct TALER_AgeCommitment *pac = NULL;
const struct TALER_EXCHANGE_DenomPublicKey *denom_pub;
const struct TALER_DenominationSignature *denom_pub_sig;
struct TALER_CoinSpendSignatureP coin_sig;
@ -382,6 +383,10 @@ deposit_run (void *cls,
TALER_TESTING_get_trait_coin_priv (coin_cmd,
ds->coin_index,
&coin_priv)) ||
(GNUNET_OK !=
TALER_TESTING_get_trait_age_commitment (coin_cmd,
ds->coin_index,
&pac)) ||
(GNUNET_OK !=
TALER_TESTING_get_trait_denom_pub (coin_cmd,
ds->coin_index,
@ -447,6 +452,7 @@ deposit_run (void *cls,
&h_contract_terms,
NULL, /* FIXME: extension object */
&coin_pub,
pac,
denom_pub_sig,
&denom_pub->key,
ds->wallet_timestamp,
@ -520,6 +526,7 @@ deposit_traits (void *cls,
const struct TALER_TESTING_Command *coin_cmd;
/* Will point to coin cmd internals. */
const struct TALER_CoinSpendPrivateKeyP *coin_spent_priv;
struct TALER_AgeCommitment *age_commitment;
if (GNUNET_YES != ds->command_initialized)
{
@ -540,7 +547,11 @@ deposit_traits (void *cls,
if (GNUNET_OK !=
TALER_TESTING_get_trait_coin_priv (coin_cmd,
ds->coin_index,
&coin_spent_priv))
&coin_spent_priv) ||
(GNUNET_OK !=
TALER_TESTING_get_trait_age_commitment (coin_cmd,
ds->coin_index,
&age_commitment)))
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (ds->is);
@ -555,6 +566,8 @@ deposit_traits (void *cls,
/* These traits are always available */
TALER_TESTING_make_trait_coin_priv (0,
coin_spent_priv),
TALER_TESTING_make_trait_age_commitment (0,
age_commitment),
TALER_TESTING_make_trait_wire_details (ds->wire_details),
TALER_TESTING_make_trait_contract_terms (ds->contract_terms),
TALER_TESTING_make_trait_merchant_priv (&ds->merchant_priv),

View File

@ -70,6 +70,11 @@ struct TALER_TESTING_FreshCoinData
*/
struct TALER_CoinSpendPrivateKeyP coin_priv;
/*
* Age commitment for the coin, NULL if not applicable.
*/
struct TALER_AgeCommitment *age_commitment;
/**
* The blinding key (needed for recoup operations).
*/
@ -124,7 +129,7 @@ struct RefreshMeltState
/*
* Age commitment for the coin, NULL if not applicable.
*/
const struct TALER_AgeCommitment *age_commitment;
struct TALER_AgeCommitment *age_commitment;
/**
* Task scheduled to try later.
@ -1018,6 +1023,16 @@ melt_run (void *cls,
return;
}
if (GNUNET_OK !=
TALER_TESTING_get_trait_age_commitment (coin_command,
0,
&rms->age_commitment))
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (rms->is);
return;
}
if (GNUNET_OK !=
TALER_TESTING_get_trait_denom_sig (coin_command,
0,
@ -1198,6 +1213,8 @@ melt_traits (void *cls,
&rms->fresh_pks[index]),
TALER_TESTING_make_trait_coin_priv (0,
rms->melt_priv),
TALER_TESTING_make_trait_age_commitment (index,
rms->age_commitment),
TALER_TESTING_trait_end ()
};
@ -1356,6 +1373,9 @@ refresh_reveal_traits (void *cls,
TALER_TESTING_make_trait_coin_priv (
index,
&rrs->fresh_coins[index].coin_priv),
TALER_TESTING_make_trait_age_commitment (
index,
rrs->fresh_coins[index].age_commitment),
TALER_TESTING_make_trait_denom_pub (
index,
rrs->fresh_coins[index].pk),

View File

@ -27,6 +27,7 @@
#include <microhttpd.h>
#include <gnunet/gnunet_curl_lib.h>
#include "taler_signatures.h"
#include "taler_extensions.h"
#include "taler_testing_lib.h"
#include "backoff.h"
@ -452,31 +453,6 @@ withdraw_run (void *cls,
ws->amount = ws->pk->value;
}
if (ws->age > 0)
{
uint32_t seed;
struct TALER_AgeCommitment *ac;
ac = GNUNET_malloc (sizeof(struct TALER_AgeCommitment));
seed = GNUNET_CRYPTO_random_u32 (
GNUNET_CRYPTO_QUALITY_WEAK,
UINT32_MAX);
GNUNET_assert (GNUNET_OK ==
TALER_age_restriction_commit (
&ws->pk->key.age_mask,
ws->age,
seed,
ac));
ws->age_commitment = ac;
ws->h_age_commitment = GNUNET_malloc (sizeof(struct
TALER_AgeCommitmentHash));
TALER_age_commitment_hash (
ac,
ws->h_age_commitment);
}
ws->reserve_history.type = TALER_EXCHANGE_RTT_WITHDRAWAL;
GNUNET_assert (0 <=
TALER_amount_add (&ws->reserve_history.amount,
@ -535,6 +511,16 @@ withdraw_cleanup (void *cls,
TALER_EXCHANGE_destroy_denomination_key (ws->pk);
ws->pk = NULL;
}
if (NULL != ws->age_commitment)
{
GNUNET_free (ws->age_commitment);
ws->age_commitment = NULL;
}
if (NULL != ws->h_age_commitment)
{
GNUNET_free (ws->h_age_commitment);
ws->h_age_commitment = NULL;
}
GNUNET_free (ws->exchange_url);
GNUNET_free (ws->reserve_payto_uri);
GNUNET_free (ws);
@ -561,13 +547,15 @@ withdraw_traits (void *cls,
struct TALER_TESTING_Trait traits[] = {
/* history entry MUST be first due to response code logic below! */
TALER_TESTING_make_trait_reserve_history (&ws->reserve_history),
TALER_TESTING_make_trait_coin_priv (0 /* only one coin */,
TALER_TESTING_make_trait_coin_priv (index /* only one coin */,
&ws->ps.coin_priv),
TALER_TESTING_make_trait_blinding_key (0 /* only one coin */,
TALER_TESTING_make_trait_age_commitment (index, ws->age_commitment),
TALER_TESTING_make_trait_h_age_commitment (index, ws->h_age_commitment),
TALER_TESTING_make_trait_blinding_key (index /* only one coin */,
&ws->ps.blinding_key),
TALER_TESTING_make_trait_denom_pub (0 /* only one coin */,
TALER_TESTING_make_trait_denom_pub (index /* only one coin */,
ws->pk),
TALER_TESTING_make_trait_denom_sig (0 /* only one coin */,
TALER_TESTING_make_trait_denom_sig (index /* only one coin */,
&ws->sig),
TALER_TESTING_make_trait_reserve_priv (&ws->reserve_priv),
TALER_TESTING_make_trait_reserve_pub (&ws->reserve_pub),
@ -611,7 +599,39 @@ TALER_TESTING_cmd_withdraw_amount (const char *label,
struct WithdrawState *ws;
ws = GNUNET_new (struct WithdrawState);
ws->age = age;
if (age > 0)
{
struct TALER_AgeCommitment *ac;
struct TALER_AgeCommitmentHash *hac;
uint32_t seed;
struct TALER_AgeMask mask;
ac = GNUNET_new (struct TALER_AgeCommitment);
hac = GNUNET_new (struct TALER_AgeCommitmentHash);
seed = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX);
mask.mask = TALER_EXTENSION_AGE_RESTRICTION_DEFAULT_AGE_MASK;
if (GNUNET_OK !=
TALER_age_restriction_commit (
&mask,
age,
seed,
ac))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to generate age commitment for age %d at %s\n",
age,
label);
GNUNET_assert (0);
}
TALER_age_commitment_hash (ac,hac);
ws->age_commitment = ac;
ws->h_age_commitment = hac;
}
ws->reserve_reference = reserve_reference;
if (GNUNET_OK !=
TALER_string_to_amount (amount,