diff options
Diffstat (limited to 'src/exchangedb/test_exchangedb.c')
-rw-r--r-- | src/exchangedb/test_exchangedb.c | 1085 |
1 files changed, 604 insertions, 481 deletions
diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c index 6724e7b42..22788a562 100644 --- a/src/exchangedb/test_exchangedb.c +++ b/src/exchangedb/test_exchangedb.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2021 Taler Systems SA + Copyright (C) 2014-2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -33,9 +33,9 @@ static int result; /** * Report line of error if @a cond is true, and jump to label "drop". */ -#define FAILIF(cond) \ +#define FAILIF(cond) \ do { \ - if (! (cond)) { break;} \ + if (! (cond)) { break;} \ GNUNET_break (0); \ goto drop; \ } while (0) @@ -45,7 +45,8 @@ static int result; * Initializes @a ptr with random data. */ #define RND_BLK(ptr) \ - GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, ptr, sizeof (*ptr)) + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, ptr, \ + sizeof (*ptr)) /** * Initializes @a ptr with zeros. @@ -109,6 +110,64 @@ mark_prepare_cb (void *cls, /** + * Simple check that config retrieval and setting for extensions work + */ +static enum GNUNET_GenericReturnValue +test_extension_manifest (void) +{ + char *manifest; + + FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != + plugin->get_extension_manifest (plugin->cls, + "fnord", + &manifest)); + + FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + plugin->set_extension_manifest (plugin->cls, + "fnord", + "bar")); + FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + plugin->get_extension_manifest (plugin->cls, + "fnord", + &manifest)); + + FAILIF (0 != strcmp ("bar", manifest)); + GNUNET_free (manifest); + + /* let's do this again! */ + FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + plugin->set_extension_manifest (plugin->cls, + "fnord", + "buzz")); + + FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + plugin->get_extension_manifest (plugin->cls, + "fnord", + &manifest)); + + FAILIF (0 != strcmp ("buzz", manifest)); + GNUNET_free (manifest); + + /* let's do this again, with NULL */ + FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + plugin->set_extension_manifest (plugin->cls, + "fnord", + NULL)); + + FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + plugin->get_extension_manifest (plugin->cls, + "fnord", + &manifest)); + + FAILIF (NULL != manifest); + + return GNUNET_OK; +drop: + return GNUNET_SYSERR; +} + + +/** * Test API relating to persisting the wire plugins preparation data. * * @return #GNUNET_OK on success @@ -162,18 +221,15 @@ check_reserve (const struct TALER_ReservePublicKeyP *pub, const char *currency) { struct TALER_EXCHANGEDB_Reserve reserve; - struct TALER_EXCHANGEDB_KycStatus kyc; reserve.pub = *pub; FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->reserves_get (plugin->cls, - &reserve, - &kyc)); + &reserve)); FAILIF (value != reserve.balance.value); FAILIF (fraction != reserve.balance.fraction); FAILIF (0 != strcmp (currency, reserve.balance.currency)); - FAILIF (kyc.ok); return GNUNET_OK; drop: return GNUNET_SYSERR; @@ -206,30 +262,24 @@ destroy_denom_key_pair (struct DenomKeyPair *dkp) * * @param size the size of the denomination key * @param now time to use for key generation, legal expiration will be 3h later. - * @param fee_withdraw withdraw fee to use - * @param fee_deposit deposit fee to use - * @param fee_refresh refresh fee to use - * @param fee_refund refund fee to use + * @param fees fees to use * @return the denominaiton key pair; NULL upon error */ static struct DenomKeyPair * create_denom_key_pair (unsigned int size, struct GNUNET_TIME_Timestamp now, const struct TALER_Amount *value, - const struct TALER_Amount *fee_withdraw, - const struct TALER_Amount *fee_deposit, - const struct TALER_Amount *fee_refresh, - const struct TALER_Amount *fee_refund) + const struct TALER_DenomFeeSet *fees) { struct DenomKeyPair *dkp; struct TALER_EXCHANGEDB_DenominationKey dki; - struct TALER_EXCHANGEDB_DenominationKeyInformationP issue2; + struct TALER_EXCHANGEDB_DenominationKeyInformation issue2; dkp = GNUNET_new (struct DenomKeyPair); GNUNET_assert (GNUNET_OK == TALER_denom_priv_create (&dkp->priv, &dkp->pub, - TALER_DENOMINATION_RSA, + GNUNET_CRYPTO_BSA_RSA, size)); /* Using memset() as fields like master key and signature are not properly initialized for this test. */ @@ -237,39 +287,28 @@ create_denom_key_pair (unsigned int size, 0, sizeof (struct TALER_EXCHANGEDB_DenominationKey)); dki.denom_pub = dkp->pub; - dki.issue.properties.start = GNUNET_TIME_timestamp_hton (now); - dki.issue.properties.expire_withdraw - = GNUNET_TIME_timestamp_hton - (GNUNET_TIME_absolute_to_timestamp - (GNUNET_TIME_absolute_add ( - now.abs_time, - GNUNET_TIME_UNIT_HOURS))); - dki.issue.properties.expire_deposit - = GNUNET_TIME_timestamp_hton ( - GNUNET_TIME_absolute_to_timestamp - (GNUNET_TIME_absolute_add - (now.abs_time, - GNUNET_TIME_relative_multiply ( - GNUNET_TIME_UNIT_HOURS, 2)))); - dki.issue.properties.expire_legal - = GNUNET_TIME_timestamp_hton ( - GNUNET_TIME_absolute_to_timestamp - (GNUNET_TIME_absolute_add - (now.abs_time, - GNUNET_TIME_relative_multiply ( - GNUNET_TIME_UNIT_HOURS, 3)))); - TALER_amount_hton (&dki.issue.properties.value, value); - TALER_amount_hton (&dki.issue.properties.fee_withdraw, fee_withdraw); - TALER_amount_hton (&dki.issue.properties.fee_deposit, fee_deposit); - TALER_amount_hton (&dki.issue.properties.fee_refresh, fee_refresh); - TALER_amount_hton (&dki.issue.properties.fee_refund, fee_refund); + dki.issue.start = now; + dki.issue.expire_withdraw + = GNUNET_TIME_absolute_to_timestamp ( + GNUNET_TIME_absolute_add ( + now.abs_time, + GNUNET_TIME_UNIT_HOURS)); + dki.issue.expire_deposit + = GNUNET_TIME_absolute_to_timestamp ( + GNUNET_TIME_absolute_add ( + now.abs_time, + GNUNET_TIME_relative_multiply ( + GNUNET_TIME_UNIT_HOURS, 2))); + dki.issue.expire_legal + = GNUNET_TIME_absolute_to_timestamp ( + GNUNET_TIME_absolute_add ( + now.abs_time, + GNUNET_TIME_relative_multiply ( + GNUNET_TIME_UNIT_HOURS, 3))); + dki.issue.value = *value; + dki.issue.fees = *fees; TALER_denom_pub_hash (&dkp->pub, - &dki.issue.properties.denom_hash); - - dki.issue.properties.purpose.size - = htonl (sizeof (struct TALER_DenominationKeyValidityPS)); - dki.issue.properties.purpose.purpose = htonl ( - TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY); + &dki.issue.denom_hash); if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->insert_denomination_info (plugin->cls, &dki.denom_pub, @@ -280,10 +319,9 @@ create_denom_key_pair (unsigned int size, return NULL; } memset (&issue2, 0, sizeof (issue2)); - plugin->commit (plugin->cls); if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->get_denomination_info (plugin->cls, - &dki.issue.properties.denom_hash, + &dki.issue.denom_hash, &issue2)) { GNUNET_break (0); @@ -302,10 +340,7 @@ create_denom_key_pair (unsigned int size, static struct TALER_Amount value; -static struct TALER_Amount fee_withdraw; -static struct TALER_Amount fee_deposit; -static struct TALER_Amount fee_refresh; -static struct TALER_Amount fee_refund; +static struct TALER_DenomFeeSet fees; static struct TALER_Amount fee_closing; static struct TALER_Amount amount_with_fee; @@ -376,10 +411,9 @@ check_refresh_reveal_cb ( &revealed_coins[cnt]; const struct TALER_EXCHANGEDB_RefreshRevealedCoin *bcoin = &rrcs[cnt]; - GNUNET_assert (acoin->coin_ev_size == bcoin->coin_ev_size); GNUNET_assert (0 == - GNUNET_memcmp (acoin->coin_ev, - bcoin->coin_ev)); + TALER_blinded_planchet_cmp (&acoin->blinded_planchet, + &bcoin->blinded_planchet)); GNUNET_assert (0 == GNUNET_memcmp (&acoin->h_denom_pub, &bcoin->h_denom_pub)); @@ -402,6 +436,7 @@ static unsigned int auditor_row_cnt; * @param cls closure * @param rowid unique serial ID for the refresh session in our DB * @param denom_pub denomination of the @a coin_pub + * @param h_age_commitment hash of age commitment that went into the minting, may be NULL * @param coin_pub public key of the coin * @param coin_sig signature from the coin * @param amount_with_fee amount that was deposited including fee @@ -411,14 +446,16 @@ static unsigned int auditor_row_cnt; * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop */ static enum GNUNET_GenericReturnValue -audit_refresh_session_cb (void *cls, - uint64_t rowid, - const struct TALER_DenominationPublicKey *denom_pub, - const struct TALER_CoinSpendPublicKeyP *coin_pub, - const struct TALER_CoinSpendSignatureP *coin_sig, - const struct TALER_Amount *amount_with_fee, - uint32_t noreveal_index, - const struct TALER_RefreshCommitmentP *rc) +audit_refresh_session_cb ( + void *cls, + uint64_t rowid, + const struct TALER_DenominationPublicKey *denom_pub, + const struct TALER_AgeCommitmentHash *h_age_commitment, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_CoinSpendSignatureP *coin_sig, + const struct TALER_Amount *amount_with_fee, + uint32_t noreveal_index, + const struct TALER_RefreshCommitmentP *rc) { (void) cls; (void) rowid; @@ -428,6 +465,7 @@ audit_refresh_session_cb (void *cls, (void) amount_with_fee; (void) noreveal_index; (void) rc; + (void) h_age_commitment; auditor_row_cnt++; return GNUNET_OK; } @@ -474,7 +512,7 @@ handle_link_data_cb (void *cls, break; } } - GNUNET_assert (found); + GNUNET_assert (GNUNET_NO != found); } } @@ -487,8 +525,9 @@ cb_wt_never (void *cls, uint64_t serial_id, const struct TALER_MerchantPublicKeyP *merchant_pub, const char *account_payto_uri, + const struct TALER_PaytoHashP *h_payto, struct GNUNET_TIME_Timestamp exec_time, - const struct TALER_PrivateContractHash *h_contract_terms, + const struct TALER_PrivateContractHashP *h_contract_terms, const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_Amount *coin_value, @@ -498,6 +537,7 @@ cb_wt_never (void *cls, (void) serial_id; (void) merchant_pub; (void) account_payto_uri; + (void) h_payto; (void) exec_time; (void) h_contract_terms; (void) denom_pub; @@ -509,8 +549,8 @@ cb_wt_never (void *cls, static struct TALER_MerchantPublicKeyP merchant_pub_wt; -static struct TALER_MerchantWireHash h_wire_wt; -static struct TALER_PrivateContractHash h_contract_terms_wt; +static struct TALER_MerchantWireHashP h_wire_wt; +static struct TALER_PrivateContractHashP h_contract_terms_wt; static struct TALER_CoinSpendPublicKeyP coin_pub_wt; static struct TALER_Amount coin_value_wt; static struct TALER_Amount coin_fee_wt; @@ -527,8 +567,9 @@ cb_wt_check (void *cls, uint64_t rowid, const struct TALER_MerchantPublicKeyP *merchant_pub, const char *account_payto_uri, + const struct TALER_PaytoHashP *h_payto, struct GNUNET_TIME_Timestamp exec_time, - const struct TALER_PrivateContractHash *h_contract_terms, + const struct TALER_PrivateContractHashP *h_contract_terms, const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_Amount *coin_value, @@ -536,6 +577,7 @@ cb_wt_check (void *cls, { (void) rowid; (void) denom_pub; + (void) h_payto; GNUNET_assert (cls == &cb_wt_never); GNUNET_assert (0 == GNUNET_memcmp (merchant_pub, &merchant_pub_wt)); @@ -556,111 +598,13 @@ cb_wt_check (void *cls, /** - * Here #deposit_cb() will store the row ID of the deposit. - */ -static uint64_t deposit_rowid; - -/** - * Here #deposit_cb() will store the row ID of the account. - */ -static uint64_t wire_target_row; - - -/** - * Function called with details about deposits that - * have been made. Called in the test on the - * deposit given in @a cls. - * - * @param cls closure a `struct TALER_EXCHANGEDB_Deposit *` - * @param rowid unique ID for the deposit in our DB, used for marking - * it as 'tiny' or 'done' - * @param merchant_pub public key of the merchant - * @param coin_pub public key of the coin - * @param amount_with_fee amount that was deposited including fee - * @param deposit_fee amount the exchange gets to keep as transaction fees - * @param h_contract_terms hash of the proposal data known to merchant and customer - * @param wire_target unique ID of the receiver account - * @param payto_uri how to pay the merchant, URI in payto://-format; - * @return transaction status code, #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT to continue to iterate - */ -static enum GNUNET_DB_QueryStatus -deposit_cb (void *cls, - uint64_t rowid, - const struct TALER_MerchantPublicKeyP *merchant_pub, - const struct TALER_CoinSpendPublicKeyP *coin_pub, - const struct TALER_Amount *amount_with_fee, - const struct TALER_Amount *deposit_fee, - const struct TALER_PrivateContractHash *h_contract_terms, - uint64_t wire_target, - const char *payto_uri) -{ - struct TALER_EXCHANGEDB_Deposit *deposit = cls; - - if ( (0 == GNUNET_memcmp (merchant_pub, - &deposit->merchant_pub)) && - (0 == TALER_amount_cmp (amount_with_fee, - &deposit->amount_with_fee)) && - (0 == TALER_amount_cmp (deposit_fee, - &deposit->deposit_fee)) && - (0 == GNUNET_memcmp (h_contract_terms, - &deposit->h_contract_terms)) && - (0 == GNUNET_memcmp (coin_pub, - &deposit->coin.coin_pub)) && - (0 == strcmp (payto_uri, - deposit->receiver_wire_account)) ) - { - deposit_rowid = rowid; - wire_target_row = wire_target; - result = 9; - } - return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; -} - - -/** - * Function called with details about deposits that - * have been made. Called in the test on the - * deposit given in @a cls. - * - * @param cls closure a `struct TALER_EXCHANGEDB_Deposit *` - * @param rowid unique ID for the deposit in our DB, used for marking - * it as 'tiny' or 'done' - * @param coin_pub public key of the coin - * @param amount_with_fee amount that was deposited including fee - * @param deposit_fee amount the exchange gets to keep as transaction fees - * @param h_contract_terms hash of the proposal data known to merchant and customer - * @return transaction status code, #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT to continue to iterate + * Here we store the hash of the payto URI. */ -static enum GNUNET_DB_QueryStatus -matching_deposit_cb (void *cls, - uint64_t rowid, - const struct TALER_CoinSpendPublicKeyP *coin_pub, - const struct TALER_Amount *amount_with_fee, - const struct TALER_Amount *deposit_fee, - const struct TALER_PrivateContractHash *h_contract_terms) -{ - struct TALER_EXCHANGEDB_Deposit *deposit = cls; - - deposit_rowid = rowid; - if ( (0 != TALER_amount_cmp (amount_with_fee, - &deposit->amount_with_fee)) || - (0 != TALER_amount_cmp (deposit_fee, - &deposit->deposit_fee)) || - (0 != GNUNET_memcmp (h_contract_terms, - &deposit->h_contract_terms)) || - (0 != GNUNET_memcmp (coin_pub, - &deposit->coin.coin_pub)) ) - { - GNUNET_break (0); - return GNUNET_DB_STATUS_HARD_ERROR; - } - - return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; -} +static struct TALER_PaytoHashP wire_target_h_payto; /** - * Callback for #select_deposits_above_serial_id () + * Callback for #select_coin_deposits_above_serial_id () * * @param cls closure * @param rowid unique serial ID for the deposit in our DB @@ -702,6 +646,7 @@ audit_deposit_cb (void *cls, * @param h_contract_terms hash of the proposal data in * the contract between merchant and customer * @param rtransaction_id refund transaction ID chosen by the merchant + * @param full_refund the deposit * @param amount_with_fee amount that was deposited including fee * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop */ @@ -712,8 +657,9 @@ audit_refund_cb (void *cls, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_MerchantSignatureP *merchant_sig, - const struct TALER_PrivateContractHash *h_contract_terms, + const struct TALER_PrivateContractHashP *h_contract_terms, uint64_t rtransaction_id, + bool full_refund, const struct TALER_Amount *amount_with_fee) { (void) cls; @@ -725,6 +671,7 @@ audit_refund_cb (void *cls, (void) h_contract_terms; (void) rtransaction_id; (void) amount_with_fee; + (void) full_refund; auditor_row_cnt++; return GNUNET_OK; } @@ -779,7 +726,7 @@ audit_reserve_in_cb (void *cls, static enum GNUNET_GenericReturnValue audit_reserve_out_cb (void *cls, uint64_t rowid, - const struct TALER_BlindedCoinHash *h_blind_ev, + const struct TALER_BlindedCoinHashP *h_blind_ev, const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_ReserveSignatureP *reserve_sig, @@ -810,8 +757,8 @@ test_gc (void) struct DenomKeyPair *dkp; struct GNUNET_TIME_Timestamp now; struct GNUNET_TIME_Timestamp past; - struct TALER_EXCHANGEDB_DenominationKeyInformationP issue2; - struct TALER_DenominationHash denom_hash; + struct TALER_EXCHANGEDB_DenominationKeyInformation issue2; + struct TALER_DenominationHashP denom_hash; now = GNUNET_TIME_timestamp_get (); past = GNUNET_TIME_absolute_to_timestamp ( @@ -822,10 +769,7 @@ test_gc (void) dkp = create_denom_key_pair (RSA_KEY_SIZE, past, &value, - &fee_withdraw, - &fee_deposit, - &fee_refresh, - &fee_refund); + &fees); GNUNET_assert (NULL != dkp); if (GNUNET_OK != plugin->gc (plugin->cls)) @@ -861,23 +805,21 @@ test_wire_fees (void) { struct GNUNET_TIME_Timestamp start_date; struct GNUNET_TIME_Timestamp end_date; - struct TALER_Amount wire_fee; - struct TALER_Amount closing_fee; + struct TALER_WireFeeSet fees; struct TALER_MasterSignatureP master_sig; struct GNUNET_TIME_Timestamp sd; struct GNUNET_TIME_Timestamp ed; - struct TALER_Amount fee; - struct TALER_Amount fee2; + struct TALER_WireFeeSet fees2; struct TALER_MasterSignatureP ms; start_date = GNUNET_TIME_timestamp_get (); end_date = GNUNET_TIME_relative_to_timestamp (GNUNET_TIME_UNIT_MINUTES); GNUNET_assert (GNUNET_OK == TALER_string_to_amount (CURRENCY ":1.424242", - &wire_fee)); + &fees.wire)); GNUNET_assert (GNUNET_OK == TALER_string_to_amount (CURRENCY ":2.424242", - &closing_fee)); + &fees.closing)); GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &master_sig, sizeof (master_sig)); @@ -886,8 +828,7 @@ test_wire_fees (void) "wire-method", start_date, end_date, - &wire_fee, - &closing_fee, + &fees, &master_sig)) { GNUNET_break (0); @@ -898,8 +839,7 @@ test_wire_fees (void) "wire-method", start_date, end_date, - &wire_fee, - &closing_fee, + &fees, &master_sig)) { GNUNET_break (0); @@ -913,8 +853,7 @@ test_wire_fees (void) end_date, &sd, &ed, - &fee, - &fee2, + &fees2, &ms)) { GNUNET_break (0); @@ -926,8 +865,7 @@ test_wire_fees (void) start_date, &sd, &ed, - &fee, - &fee2, + &fees2, &ms)) { GNUNET_break (0); @@ -939,10 +877,8 @@ test_wire_fees (void) (GNUNET_TIME_timestamp_cmp (ed, !=, end_date)) || - (0 != TALER_amount_cmp (&fee, - &wire_fee)) || - (0 != TALER_amount_cmp (&fee2, - &closing_fee)) || + (0 != TALER_wire_fee_set_cmp (&fees, + &fees2)) || (0 != GNUNET_memcmp (&ms, &master_sig)) ) { @@ -995,14 +931,21 @@ audit_wire_cb (void *cls, /** * Test API relating to wire_out handling. * + * @param bd batch deposit to test * @return #GNUNET_OK on success */ static enum GNUNET_GenericReturnValue -test_wire_out (const struct TALER_EXCHANGEDB_Deposit *deposit) +test_wire_out (const struct TALER_EXCHANGEDB_BatchDeposit *bd) { + const struct TALER_EXCHANGEDB_CoinDepositInformation *deposit = &bd->cdis[0]; + struct TALER_PaytoHashP h_payto; + + GNUNET_assert (0 < bd->num_cdis); + TALER_payto_hash (bd->receiver_wire_account, + &h_payto); auditor_row_cnt = 0; memset (&wire_out_wtid, - 42, + 41, sizeof (wire_out_wtid)); wire_out_date = GNUNET_TIME_timestamp_get (); GNUNET_assert (GNUNET_OK == @@ -1016,12 +959,12 @@ test_wire_out (const struct TALER_EXCHANGEDB_Deposit *deposit) plugin->start_deferred_wire_out (plugin->cls)); /* setup values for wire transfer aggregation data */ - merchant_pub_wt = deposit->merchant_pub; - h_contract_terms_wt = deposit->h_contract_terms; + merchant_pub_wt = bd->merchant_pub; + h_contract_terms_wt = bd->h_contract_terms; coin_pub_wt = deposit->coin.coin_pub; coin_value_wt = deposit->amount_with_fee; - coin_fee_wt = fee_deposit; + coin_fee_wt = fees.deposit; GNUNET_assert (0 < TALER_amount_subtract (&transfer_value_wt, &coin_value_wt, @@ -1033,13 +976,15 @@ test_wire_out (const struct TALER_EXCHANGEDB_Deposit *deposit) NULL)); { - struct TALER_PrivateContractHash h_contract_terms_wt2 = h_contract_terms_wt; + struct TALER_PrivateContractHashP h_contract_terms_wt2 = + h_contract_terms_wt; bool pending; struct TALER_WireTransferIdentifierRawP wtid2; struct TALER_Amount coin_contribution2; struct TALER_Amount coin_fee2; struct GNUNET_TIME_Timestamp execution_time2; struct TALER_EXCHANGEDB_KycStatus kyc; + enum TALER_AmlDecisionState aml; h_contract_terms_wt2.hash.bits[0]++; FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != @@ -1053,32 +998,20 @@ test_wire_out (const struct TALER_EXCHANGEDB_Deposit *deposit) &execution_time2, &coin_contribution2, &coin_fee2, - &kyc)); + &kyc, + &aml)); } - /* insert WT data */ - FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != - plugin->insert_aggregation_tracking (plugin->cls, - &wire_out_wtid, - deposit_rowid)); - - /* Now let's fix the transient constraint violation by - putting in the WTID into the wire_out table */ { struct TALER_ReservePublicKeyP rpub; - struct TALER_EXCHANGEDB_KycStatus kyc; memset (&rpub, 44, sizeof (rpub)); FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != - plugin->inselect_wallet_kyc_status (plugin->cls, - &rpub, - &kyc)); - FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->store_wire_transfer_out (plugin->cls, wire_out_date, &wire_out_wtid, - kyc.payment_target_uuid, + &h_payto, "my-config-section", &wire_out_amount)); } @@ -1098,6 +1031,7 @@ test_wire_out (const struct TALER_EXCHANGEDB_Deposit *deposit) struct TALER_Amount coin_fee2; struct GNUNET_TIME_Timestamp execution_time2; struct TALER_EXCHANGEDB_KycStatus kyc; + enum TALER_AmlDecisionState aml = TALER_AML_FROZEN; FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->lookup_transfer_by_deposit (plugin->cls, @@ -1110,7 +1044,9 @@ test_wire_out (const struct TALER_EXCHANGEDB_Deposit *deposit) &execution_time2, &coin_contribution2, &coin_fee2, - &kyc)); + &kyc, + &aml)); + FAILIF (TALER_AML_NORMAL != aml); GNUNET_assert (0 == GNUNET_memcmp (&wtid2, &wire_out_wtid)); GNUNET_assert (GNUNET_TIME_timestamp_cmp (execution_time2, @@ -1157,9 +1093,9 @@ recoup_cb (void *cls, const struct TALER_CoinPublicInfo *coin, const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_CoinSpendSignatureP *coin_sig, - const union TALER_DenominationBlindingKeyP *coin_blind) + const union GNUNET_CRYPTO_BlindingSecretP *coin_blind) { - const union TALER_DenominationBlindingKeyP *cb = cls; + const union GNUNET_CRYPTO_BlindingSecretP *cb = cls; (void) rowid; (void) timestamp; @@ -1178,55 +1114,32 @@ drop: /** - * Function called on deposits that are past their due date - * and have not yet seen a wire transfer. + * Function called on batch deposits that may require a + * wire transfer. * * @param cls closure a `struct TALER_EXCHANGEDB_Deposit *` - * @param rowid deposit table row of the coin's deposit - * @param coin_pub public key of the coin - * @param amount value of the deposit, including fee - * @param payto_uri where should the funds be wired - * @param deadline what was the requested wire transfer deadline - * @param tiny did the exchange defer this transfer because it is too small? - * @param done did the exchange claim that it made a transfer? + * @param batch_deposit_serial_id where in the table are we + * @param total_amount value of all missing deposits, including fees + * @param wire_target_h_payto hash of the recipient account's payto URI + * @param deadline what was the earliest requested wire transfer deadline */ static void -wire_missing_cb (void *cls, - uint64_t rowid, - const struct TALER_CoinSpendPublicKeyP *coin_pub, - const struct TALER_Amount *amount, - const char *payto_uri, - struct GNUNET_TIME_Timestamp deadline, - bool tiny, - bool done) +wire_missing_cb ( + void *cls, + uint64_t batch_deposit_serial_id, + const struct TALER_Amount *total_amount, + const struct TALER_PaytoHashP *wire_target_h_payto, + struct GNUNET_TIME_Timestamp deadline) { - const struct TALER_EXCHANGEDB_Deposit *deposit = cls; + const struct TALER_EXCHANGEDB_CoinDepositInformation *deposit = cls; - (void) payto_uri; + (void) batch_deposit_serial_id; (void) deadline; - (void) rowid; - if (tiny) - { - GNUNET_break (0); - result = 66; - } - if (done) - { - GNUNET_break (0); - result = 66; - } - if (0 != TALER_amount_cmp (amount, - &deposit->amount_with_fee)) - { - GNUNET_break (0); - result = 66; - } - if (0 != GNUNET_memcmp (coin_pub, - &deposit->coin.coin_pub)) - { - GNUNET_break (0); - result = 66; - } + (void) wire_target_h_payto; + if (0 == + TALER_amount_cmp (total_amount, + &deposit->amount_with_fee)) + result = 8; } @@ -1265,7 +1178,7 @@ run (void *cls) struct GNUNET_CONFIGURATION_Handle *cfg = cls; struct TALER_CoinSpendSignatureP coin_sig; struct GNUNET_TIME_Timestamp deadline; - union TALER_DenominationBlindingKeyP coin_blind; + union GNUNET_CRYPTO_BlindingSecretP coin_blind; struct TALER_ReservePublicKeyP reserve_pub; struct TALER_ReservePublicKeyP reserve_pub2; struct TALER_ReservePublicKeyP reserve_pub3; @@ -1277,31 +1190,42 @@ run (void *cls) struct TALER_EXCHANGEDB_ReserveHistory *rh_head; struct TALER_EXCHANGEDB_BankTransfer *bt; struct TALER_EXCHANGEDB_CollectableBlindcoin *withdraw; - struct TALER_EXCHANGEDB_Deposit deposit; - struct TALER_EXCHANGEDB_Deposit deposit2; + struct TALER_EXCHANGEDB_CoinDepositInformation deposit; + struct TALER_EXCHANGEDB_BatchDeposit bd; + struct TALER_CoinSpendPublicKeyP cpub2; + struct TALER_MerchantPublicKeyP mpub2; struct TALER_EXCHANGEDB_Refund refund; struct TALER_EXCHANGEDB_TransactionList *tl; struct TALER_EXCHANGEDB_TransactionList *tlp; const char *sndr = "payto://x-taler-bank/localhost:8080/1"; const char *rcvr = "payto://x-taler-bank/localhost:8080/2"; + const uint32_t num_partitions = 10; unsigned int matched; unsigned int cnt; enum GNUNET_DB_QueryStatus qs; struct GNUNET_TIME_Timestamp now; - struct TALER_WireSalt salt; - union TALER_DenominationBlindingKeyP bks; - struct TALER_CoinPubHash c_hash; + struct TALER_WireSaltP salt; + struct TALER_CoinPubHashP c_hash; uint64_t known_coin_id; uint64_t rrc_serial; struct TALER_EXCHANGEDB_Refresh refresh; struct TALER_DenominationPublicKey *new_denom_pubs = NULL; uint64_t reserve_out_serial_id; uint64_t melt_serial_id; + struct TALER_PlanchetMasterSecretP ps; + union GNUNET_CRYPTO_BlindingSecretP bks; + const struct TALER_ExchangeWithdrawValues *alg_values + = TALER_denom_ewv_rsa_singleton (); memset (&deposit, 0, sizeof (deposit)); - deposit.receiver_wire_account = (char *) rcvr; + memset (&bd, + 0, + sizeof (bd)); + bd.receiver_wire_account = (char *) rcvr; + bd.cdis = &deposit; + bd.num_cdis = 1; memset (&salt, 45, sizeof (salt)); @@ -1318,10 +1242,12 @@ run (void *cls) } (void) plugin->drop_tables (plugin->cls); if (GNUNET_OK != - plugin->create_tables (plugin->cls)) + plugin->create_tables (plugin->cls, + true, + num_partitions)) { result = 77; - goto drop; + goto cleanup; } plugin->preflight (plugin->cls); FAILIF (GNUNET_OK != @@ -1334,37 +1260,52 @@ run (void *cls) 0, &recoup_cb, NULL)); + /* simple extension check */ + FAILIF (GNUNET_OK != + test_extension_manifest ()); + RND_BLK (&reserve_pub); GNUNET_assert (GNUNET_OK == TALER_string_to_amount (CURRENCY ":1.000010", &value)); GNUNET_assert (GNUNET_OK == TALER_string_to_amount (CURRENCY ":0.000010", - &fee_withdraw)); + &fees.withdraw)); GNUNET_assert (GNUNET_OK == TALER_string_to_amount (CURRENCY ":0.000010", - &fee_deposit)); - deposit.deposit_fee = fee_deposit; + &fees.deposit)); GNUNET_assert (GNUNET_OK == TALER_string_to_amount (CURRENCY ":0.000010", - &fee_refresh)); + &fees.refresh)); GNUNET_assert (GNUNET_OK == TALER_string_to_amount (CURRENCY ":0.000010", - &fee_refund)); + &fees.refund)); GNUNET_assert (GNUNET_OK == TALER_string_to_amount (CURRENCY ":1.000010", &amount_with_fee)); - result = 4; + FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != + plugin->commit (plugin->cls)); now = GNUNET_TIME_timestamp_get (); - FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != - plugin->reserves_in_insert (plugin->cls, - &reserve_pub, - &value, - now, - sndr, - "exchange-account-1", - 4)); + { + struct TALER_EXCHANGEDB_ReserveInInfo reserve = { + .reserve_pub = &reserve_pub, + .balance = &value, + .execution_time = now, + .sender_account_details = sndr, + .exchange_account_name = "exchange-account-1", + .wire_reference = 4 + }; + enum GNUNET_DB_QueryStatus qsr; + + FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + plugin->reserves_in_insert (plugin->cls, + &reserve, + 1, + &qsr)); + FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + qsr); + } FAILIF (GNUNET_OK != check_reserve (&reserve_pub, value.value, @@ -1372,14 +1313,28 @@ run (void *cls) value.currency)); now = GNUNET_TIME_timestamp_get (); RND_BLK (&reserve_pub2); - FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != - plugin->reserves_in_insert (plugin->cls, - &reserve_pub2, - &value, - now, - sndr, - "exchange-account-1", - 5)); + { + struct TALER_EXCHANGEDB_ReserveInInfo reserve = { + .reserve_pub = &reserve_pub2, + .balance = &value, + .execution_time = now, + .sender_account_details = sndr, + .exchange_account_name = "exchange-account-1", + .wire_reference = 5 + }; + enum GNUNET_DB_QueryStatus qsr; + + FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + plugin->reserves_in_insert (plugin->cls, + &reserve, + 1, + &qsr)); + FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + qsr); + } + FAILIF (GNUNET_OK != + plugin->start (plugin->cls, + "test-2")); FAILIF (GNUNET_OK != check_reserve (&reserve_pub, value.value, @@ -1395,61 +1350,101 @@ run (void *cls) dkp = create_denom_key_pair (RSA_KEY_SIZE, now, &value, - &fee_withdraw, - &fee_deposit, - &fee_refresh, - &fee_refund); + &fees); GNUNET_assert (NULL != dkp); TALER_denom_pub_hash (&dkp->pub, &cbc.denom_pub_hash); RND_BLK (&cbc.reserve_sig); + RND_BLK (&ps); + TALER_planchet_blinding_secret_create (&ps, + alg_values, + &bks); { struct TALER_PlanchetDetail pd; struct TALER_CoinSpendPublicKeyP coin_pub; + struct TALER_AgeCommitmentHash age_hash; + struct TALER_AgeCommitmentHash *p_ah[2] = { + NULL, + &age_hash + }; + + /* Call TALER_denom_blind()/TALER_denom_sign_blinded() twice, once without + * age_hash, once with age_hash */ + RND_BLK (&age_hash); + for (size_t i = 0; i < sizeof(p_ah) / sizeof(p_ah[0]); i++) + { - RND_BLK (&coin_pub); - TALER_blinding_secret_create (&bks); - GNUNET_assert (GNUNET_OK == - TALER_denom_blind (&dkp->pub, - &bks, - NULL, /* FIXME-Oec */ - &coin_pub, - &c_hash, - &pd.coin_ev, - &pd.coin_ev_size)); - TALER_coin_ev_hash (pd.coin_ev, - pd.coin_ev_size, - &cbc.h_coin_envelope); - GNUNET_assert (GNUNET_OK == - TALER_denom_sign_blinded (&cbc.sig, - &dkp->priv, - pd.coin_ev, - pd.coin_ev_size)); - GNUNET_free (pd.coin_ev); + RND_BLK (&coin_pub); + GNUNET_assert (GNUNET_OK == + TALER_denom_blind (&dkp->pub, + &bks, + NULL, + p_ah[i], + &coin_pub, + alg_values, + &c_hash, + &pd.blinded_planchet)); + TALER_coin_ev_hash (&pd.blinded_planchet, + &cbc.denom_pub_hash, + &cbc.h_coin_envelope); + if (i != 0) + TALER_blinded_denom_sig_free (&cbc.sig); + GNUNET_assert ( + GNUNET_OK == + TALER_denom_sign_blinded ( + &cbc.sig, + &dkp->priv, + false, + &pd.blinded_planchet)); + TALER_blinded_planchet_free (&pd.blinded_planchet); + } } + cbc.reserve_pub = reserve_pub; cbc.amount_with_fee = value; GNUNET_assert (GNUNET_OK == TALER_amount_set_zero (CURRENCY, &cbc.withdraw_fee)); + { bool found; + bool nonce_reuse; bool balance_ok; - struct TALER_EXCHANGEDB_KycStatus kyc; + bool age_ok; + bool conflict; + bool denom_unknown; + uint16_t maximum_age; uint64_t ruuid; + struct TALER_Amount reserve_balance; FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != - plugin->do_withdraw (plugin->cls, - &cbc, - now, - &found, - &balance_ok, - &kyc, - &ruuid)); + plugin->do_batch_withdraw (plugin->cls, + now, + &reserve_pub, + &value, + true, + &found, + &balance_ok, + &reserve_balance, + &age_ok, + &maximum_age, + &ruuid)); + FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + plugin->do_batch_withdraw_insert (plugin->cls, + NULL, + &cbc, + now, + ruuid, + &denom_unknown, + &conflict, + &nonce_reuse)); GNUNET_assert (found); + GNUNET_assert (! nonce_reuse); + GNUNET_assert (! denom_unknown); GNUNET_assert (balance_ok); - GNUNET_assert (! kyc.ok); } + + FAILIF (GNUNET_OK != check_reserve (&reserve_pub, 0, @@ -1485,6 +1480,8 @@ run (void *cls) TALER_denom_sig_unblind (&ds, &cbc2.sig, &bks, + &c_hash, + alg_values, &dkp->pub)); FAILIF (GNUNET_OK != TALER_denom_pub_verify (&dkp->pub, @@ -1502,11 +1499,13 @@ run (void *cls) TALER_denom_sig_unblind (&deposit.coin.denom_sig, &cbc.sig, &bks, + &c_hash, + alg_values, &dkp->pub)); deadline = GNUNET_TIME_timestamp_get (); { - struct TALER_DenominationHash dph; - struct TALER_AgeHash agh; + struct TALER_DenominationHashP dph; + struct TALER_AgeCommitmentHash agh; FAILIF (TALER_EXCHANGEDB_CKS_ADDED != plugin->ensure_coin_known (plugin->cls, @@ -1521,23 +1520,22 @@ run (void *cls) struct GNUNET_TIME_Timestamp deposit_timestamp = GNUNET_TIME_timestamp_get (); bool balance_ok; + uint32_t bad_balance_idx; bool in_conflict; - struct TALER_PaytoHash h_payto; + struct TALER_PaytoHashP h_payto; RND_BLK (&h_payto); - deposit.refund_deadline + bd.refund_deadline = GNUNET_TIME_relative_to_timestamp (GNUNET_TIME_UNIT_MONTHS); - deposit.wire_deadline + bd.wire_deadline = GNUNET_TIME_relative_to_timestamp (GNUNET_TIME_UNIT_MONTHS); deposit.amount_with_fee = value; FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->do_deposit (plugin->cls, - &deposit, - known_coin_id, - &h_payto, - false, + &bd, &deposit_timestamp, &balance_ok, + &bad_balance_idx, &in_conflict)); FAILIF (! balance_ok); FAILIF (in_conflict); @@ -1550,17 +1548,17 @@ run (void *cls) bool conflict; refund.coin = deposit.coin; - refund.details.merchant_pub = deposit.merchant_pub; + refund.details.merchant_pub = bd.merchant_pub; RND_BLK (&refund.details.merchant_sig); - refund.details.h_contract_terms = deposit.h_contract_terms; + refund.details.h_contract_terms = bd.h_contract_terms; refund.details.rtransaction_id = 1; refund.details.refund_amount = value; - refund.details.refund_fee = fee_refund; + refund.details.refund_fee = fees.refund; RND_BLK (&refund.details.merchant_sig); FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->do_refund (plugin->cls, &refund, - &fee_deposit, + &fees.deposit, known_coin_id, ¬_found, &refund_ok, @@ -1592,6 +1590,7 @@ run (void *cls) refresh.noreveal_index = MELT_NOREVEAL_INDEX; FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->do_melt (plugin->cls, + NULL, &refresh, known_coin_id, &zombie_required, @@ -1615,7 +1614,7 @@ run (void *cls) TALER_amount_cmp (&refresh.amount_with_fee, &ret_refresh_session.session.amount_with_fee)); FAILIF (0 != - TALER_amount_cmp (&fee_refresh, + TALER_amount_cmp (&fees.refresh, &ret_refresh_session.melt_fee)); FAILIF (0 != GNUNET_memcmp (&refresh.rc, @@ -1654,35 +1653,43 @@ run (void *cls) { struct TALER_EXCHANGEDB_RefreshRevealedCoin *ccoin; struct GNUNET_TIME_Timestamp now; + struct GNUNET_CRYPTO_BlindedMessage *rp; + struct GNUNET_CRYPTO_RsaBlindedMessage *rsa; + struct TALER_BlindedPlanchet *bp; now = GNUNET_TIME_timestamp_get (); new_dkp[cnt] = create_denom_key_pair (RSA_KEY_SIZE, now, &value, - &fee_withdraw, - &fee_deposit, - &fee_refresh, - &fee_refund); + &fees); GNUNET_assert (NULL != new_dkp[cnt]); new_denom_pubs[cnt] = new_dkp[cnt]->pub; ccoin = &revealed_coins[cnt]; - ccoin->coin_ev_size = 1 + (size_t) GNUNET_CRYPTO_random_u64 ( + bp = &ccoin->blinded_planchet; + rp = GNUNET_new (struct GNUNET_CRYPTO_BlindedMessage); + bp->blinded_message = rp; + rp->cipher = GNUNET_CRYPTO_BSA_RSA; + rp->rc = 1; + rsa = &rp->details.rsa_blinded_message; + rsa->blinded_msg_size = 1 + (size_t) GNUNET_CRYPTO_random_u64 ( GNUNET_CRYPTO_QUALITY_WEAK, (RSA_KEY_SIZE / 8) - 1); - ccoin->coin_ev = GNUNET_malloc (ccoin->coin_ev_size); + rsa->blinded_msg = GNUNET_malloc (rsa->blinded_msg_size); GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, - ccoin->coin_ev, - ccoin->coin_ev_size); - GNUNET_CRYPTO_hash (ccoin->coin_ev, - ccoin->coin_ev_size, - &ccoin->coin_envelope_hash.hash); + rsa->blinded_msg, + rsa->blinded_msg_size); TALER_denom_pub_hash (&new_dkp[cnt]->pub, &ccoin->h_denom_pub); + TALER_denom_ewv_copy (&ccoin->exchange_vals, + alg_values); + TALER_coin_ev_hash (bp, + &ccoin->h_denom_pub, + &ccoin->coin_envelope_hash); GNUNET_assert (GNUNET_OK == TALER_denom_sign_blinded (&ccoin->coin_sig, &new_dkp[cnt]->priv, - ccoin->coin_ev, - ccoin->coin_ev_size)); + true, + bp)); } RND_BLK (&tprivs); RND_BLK (&tpub); @@ -1700,13 +1707,15 @@ run (void *cls) tprivs, &tpub)); { - struct TALER_BlindedCoinHash h_coin_ev; + struct TALER_BlindedCoinHashP h_coin_ev; struct TALER_CoinSpendPublicKeyP ocp; + struct TALER_DenominationHashP denom_hash; - GNUNET_CRYPTO_hash (revealed_coins[0].coin_ev, - revealed_coins[0].coin_ev_size, - &h_coin_ev.hash); - + TALER_denom_pub_hash (&new_denom_pubs[0], + &denom_hash); + TALER_coin_ev_hash (&revealed_coins[0].blinded_planchet, + &denom_hash, + &h_coin_ev); FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->get_old_coin_by_h_blind (plugin->cls, &h_coin_ev, @@ -1730,12 +1739,20 @@ run (void *cls) /* Just to test fetching a coin with melt history */ struct TALER_EXCHANGEDB_TransactionList *tl; enum GNUNET_DB_QueryStatus qs; + uint64_t etag; + struct TALER_Amount balance; + struct TALER_DenominationHashP h_denom_pub; qs = plugin->get_coin_transactions (plugin->cls, &refresh.coin.coin_pub, - GNUNET_YES, + 0, + 0, + &etag, + &balance, + &h_denom_pub, &tl); - FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs); + FAILIF (0 >= qs); + FAILIF (NULL == tl); plugin->free_coin_transaction_list (plugin->cls, tl); } @@ -1745,11 +1762,11 @@ run (void *cls) { struct GNUNET_TIME_Timestamp recoup_timestamp = GNUNET_TIME_timestamp_get (); - union TALER_DenominationBlindingKeyP coin_bks; + union GNUNET_CRYPTO_BlindingSecretP coin_bks; uint64_t new_known_coin_id; struct TALER_CoinPublicInfo new_coin; - struct TALER_DenominationHash dph; - struct TALER_AgeHash agh; + struct TALER_DenominationHashP dph; + struct TALER_AgeCommitmentHash agh; bool recoup_ok; bool internal_failure; @@ -1782,7 +1799,6 @@ run (void *cls) struct TALER_EXCHANGEDB_Reserve pre_reserve; struct TALER_EXCHANGEDB_Reserve post_reserve; struct TALER_Amount delta; - struct TALER_EXCHANGEDB_KycStatus kyc; bool recoup_ok; bool internal_failure; struct GNUNET_TIME_Timestamp recoup_timestamp @@ -1791,8 +1807,7 @@ run (void *cls) pre_reserve.pub = reserve_pub; FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->reserves_get (plugin->cls, - &pre_reserve, - &kyc)); + &pre_reserve)); FAILIF (! TALER_amount_is_zero (&pre_reserve.balance)); FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->do_recoup (plugin->cls, @@ -1810,8 +1825,7 @@ run (void *cls) post_reserve.pub = reserve_pub; FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->reserves_get (plugin->cls, - &post_reserve, - &kyc)); + &post_reserve)); FAILIF (0 >= TALER_amount_subtract (&delta, &post_reserve.balance, @@ -1842,7 +1856,8 @@ run (void *cls) sndr, &wire_out_wtid, &amount_with_fee, - &fee_closing)); + &fee_closing, + 0)); FAILIF (GNUNET_OK != check_reserve (&reserve_pub2, 0, @@ -1856,20 +1871,27 @@ run (void *cls) sndr, &wire_out_wtid, &value, - &fee_closing)); + &fee_closing, + 0)); FAILIF (GNUNET_OK != check_reserve (&reserve_pub, 0, 0, value.currency)); result = 7; + FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != + plugin->commit (plugin->cls)); /* check reserve history */ { struct TALER_Amount balance; + uint64_t etag_out; qs = plugin->get_reserve_history (plugin->cls, &reserve_pub, + 0, + 0, + &etag_out, &balance, &rh); } @@ -1935,8 +1957,29 @@ run (void *cls) &fee_closing)); } break; + case TALER_EXCHANGEDB_RO_PURSE_MERGE: + { + /* FIXME: not yet tested */ + break; + } + case TALER_EXCHANGEDB_RO_HISTORY_REQUEST: + { + /* FIXME: not yet tested */ + break; + } + case TALER_EXCHANGEDB_RO_OPEN_REQUEST: + { + /* FIXME: not yet tested */ + break; + } + case TALER_EXCHANGEDB_RO_CLOSE_REQUEST: + { + /* FIXME: not yet tested */ + break; + } } } + GNUNET_assert (4 == cnt); FAILIF (4 != cnt); auditor_row_cnt = 0; @@ -1960,10 +2003,20 @@ run (void *cls) &audit_refund_cb, NULL)); FAILIF (1 != auditor_row_cnt); - qs = plugin->get_coin_transactions (plugin->cls, - &refund.coin.coin_pub, - GNUNET_YES, - &tl); + { + uint64_t etag = 0; + struct TALER_Amount balance; + struct TALER_DenominationHashP h_denom_pub; + + qs = plugin->get_coin_transactions (plugin->cls, + &refund.coin.coin_pub, + 0, + 0, + &etag, + &balance, + &h_denom_pub, + &tl); + } FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs); GNUNET_assert (NULL != tl); matched = 0; @@ -1983,26 +2036,24 @@ run (void *cls) &deposit.csig)); FAILIF (0 != GNUNET_memcmp (&have->merchant_pub, - &deposit.merchant_pub)); + &bd.merchant_pub)); FAILIF (0 != GNUNET_memcmp (&have->h_contract_terms, - &deposit.h_contract_terms)); + &bd.h_contract_terms)); FAILIF (0 != GNUNET_memcmp (&have->wire_salt, - &deposit.wire_salt)); + &bd.wire_salt)); FAILIF (GNUNET_TIME_timestamp_cmp (have->timestamp, !=, - deposit.timestamp)); + bd.wallet_timestamp)); FAILIF (GNUNET_TIME_timestamp_cmp (have->refund_deadline, !=, - deposit.refund_deadline)); + bd.refund_deadline)); FAILIF (GNUNET_TIME_timestamp_cmp (have->wire_deadline, !=, - deposit.wire_deadline)); + bd.wire_deadline)); FAILIF (0 != TALER_amount_cmp (&have->amount_with_fee, &deposit.amount_with_fee)); - FAILIF (0 != TALER_amount_cmp (&have->deposit_fee, - &deposit.deposit_fee)); matched |= 1; break; } @@ -2073,7 +2124,6 @@ run (void *cls) memset (&deposit, 0, sizeof (deposit)); - deposit.deposit_fee = fee_deposit; RND_BLK (&deposit.coin.coin_pub); TALER_denom_pub_hash (&dkp->pub, &deposit.coin.denom_pub_hash); @@ -2081,27 +2131,30 @@ run (void *cls) TALER_denom_sig_unblind (&deposit.coin.denom_sig, &cbc.sig, &bks, + &c_hash, + alg_values, &dkp->pub)); RND_BLK (&deposit.csig); - RND_BLK (&deposit.merchant_pub); - RND_BLK (&deposit.h_contract_terms); - RND_BLK (&deposit.wire_salt); - deposit.receiver_wire_account = + RND_BLK (&bd.merchant_pub); + RND_BLK (&bd.h_contract_terms); + RND_BLK (&bd.wire_salt); + bd.receiver_wire_account = "payto://iban/DE67830654080004822650?receiver-name=Test"; TALER_merchant_wire_signature_hash ( "payto://iban/DE67830654080004822650?receiver-name=Test", - &deposit.wire_salt, + &bd.wire_salt, &h_wire_wt); deposit.amount_with_fee = value; - deposit.deposit_fee = fee_deposit; - - deposit.refund_deadline = deadline; - deposit.wire_deadline = deadline; + bd.refund_deadline = deadline; + bd.wire_deadline = deadline; result = 8; + FAILIF (GNUNET_OK != + plugin->start (plugin->cls, + "test-3")); { uint64_t known_coin_id; - struct TALER_DenominationHash dph; - struct TALER_AgeHash agh; + struct TALER_DenominationHashP dph; + struct TALER_AgeCommitmentHash agh; FAILIF (TALER_EXCHANGEDB_CKS_ADDED != plugin->ensure_coin_known (plugin->cls, @@ -2114,23 +2167,31 @@ run (void *cls) struct GNUNET_TIME_Timestamp now; struct GNUNET_TIME_Timestamp r; struct TALER_Amount deposit_fee; - struct TALER_MerchantWireHash h_wire; + struct TALER_MerchantWireHashP h_wire; + bool balance_ok; + uint32_t bad_idx; + bool ctr_conflict; now = GNUNET_TIME_timestamp_get (); + TALER_payto_hash (bd.receiver_wire_account, + &bd.wire_target_h_payto); FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != - plugin->insert_deposit (plugin->cls, - now, - &deposit)); - TALER_merchant_wire_signature_hash (deposit.receiver_wire_account, - &deposit.wire_salt, + plugin->do_deposit (plugin->cls, + &bd, + &now, + &balance_ok, + &bad_idx, + &ctr_conflict)); + TALER_merchant_wire_signature_hash (bd.receiver_wire_account, + &bd.wire_salt, &h_wire); FAILIF (1 != plugin->have_deposit2 (plugin->cls, - &deposit.h_contract_terms, + &bd.h_contract_terms, &h_wire, &deposit.coin.coin_pub, - &deposit.merchant_pub, - deposit.refund_deadline, + &bd.merchant_pub, + bd.refund_deadline, &deposit_fee, &r)); FAILIF (GNUNET_TIME_timestamp_cmp (now, @@ -2138,111 +2199,168 @@ run (void *cls) r)); } { - struct GNUNET_TIME_Timestamp start_range; - struct GNUNET_TIME_Timestamp end_range; - - start_range = GNUNET_TIME_absolute_to_timestamp ( - GNUNET_TIME_absolute_subtract (deadline.abs_time, - GNUNET_TIME_UNIT_SECONDS)); - end_range = GNUNET_TIME_absolute_to_timestamp ( - GNUNET_TIME_absolute_add (deadline.abs_time, - GNUNET_TIME_UNIT_SECONDS)); - FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != - plugin->select_deposits_missing_wire (plugin->cls, - start_range, - end_range, - &wire_missing_cb, - &deposit)); + result = 66; + FAILIF (0 >= + plugin->select_batch_deposits_missing_wire (plugin->cls, + 0, + &wire_missing_cb, + &deposit)); FAILIF (8 != result); } auditor_row_cnt = 0; FAILIF (0 >= - plugin->select_deposits_above_serial_id (plugin->cls, - 0, - &audit_deposit_cb, - NULL)); + plugin->select_coin_deposits_above_serial_id (plugin->cls, + 0, + &audit_deposit_cb, + NULL)); FAILIF (0 == auditor_row_cnt); result = 8; sleep (2); /* give deposit time to be ready */ - FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != - plugin->get_ready_deposit (plugin->cls, - 0, - INT32_MAX, - true, - &deposit_cb, - &deposit)); - FAILIF (8 == result); - FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != - plugin->iterate_matching_deposits (plugin->cls, - wire_target_row, - &deposit.merchant_pub, - &matching_deposit_cb, - &deposit, - 2)); + { + struct TALER_MerchantPublicKeyP merchant_pub2; + char *payto_uri2; + + FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + plugin->get_ready_deposit (plugin->cls, + 0, + INT32_MAX, + &merchant_pub2, + &payto_uri2)); + FAILIF (0 != GNUNET_memcmp (&merchant_pub2, + &bd.merchant_pub)); + FAILIF (0 != strcmp (payto_uri2, + bd.receiver_wire_account)); + TALER_payto_hash (payto_uri2, + &wire_target_h_payto); + GNUNET_free (payto_uri2); + } + + { + struct TALER_Amount total; + struct TALER_WireTransferIdentifierRawP wtid; + + memset (&wtid, + 41, + sizeof (wtid)); + FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + plugin->aggregate (plugin->cls, + &wire_target_h_payto, + &bd.merchant_pub, + &wtid, + &total)); + } FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != plugin->commit (plugin->cls)); FAILIF (GNUNET_OK != plugin->start (plugin->cls, - "test-2")); - FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != - plugin->mark_deposit_tiny (plugin->cls, - deposit_rowid)); - FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != - plugin->get_ready_deposit (plugin->cls, - 0, - INT32_MAX, - true, - &deposit_cb, - &deposit)); - plugin->rollback (plugin->cls); - FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != - plugin->get_ready_deposit (plugin->cls, - 0, - INT32_MAX, - true, - &deposit_cb, - &deposit)); - FAILIF (GNUNET_OK != - plugin->start (plugin->cls, "test-3")); - FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != - plugin->mark_deposit_done (plugin->cls, - deposit_rowid)); + { + struct TALER_WireTransferIdentifierRawP wtid; + struct TALER_Amount total; + struct TALER_WireTransferIdentifierRawP wtid2; + struct TALER_Amount total2; + + memset (&wtid, + 42, + sizeof (wtid)); + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount (CURRENCY ":42", + &total)); + FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != + plugin->select_aggregation_transient (plugin->cls, + &wire_target_h_payto, + &bd.merchant_pub, + "x-bank", + &wtid2, + &total2)); + FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + plugin->create_aggregation_transient (plugin->cls, + &wire_target_h_payto, + "x-bank", + &bd.merchant_pub, + &wtid, + 0, + &total)); + FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + plugin->select_aggregation_transient (plugin->cls, + &wire_target_h_payto, + &bd.merchant_pub, + "x-bank", + &wtid2, + &total2)); + FAILIF (0 != + GNUNET_memcmp (&wtid2, + &wtid)); + FAILIF (0 != + TALER_amount_cmp (&total2, + &total)); + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount (CURRENCY ":43", + &total)); + FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + plugin->update_aggregation_transient (plugin->cls, + &wire_target_h_payto, + &wtid, + 0, + &total)); + FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + plugin->select_aggregation_transient (plugin->cls, + &wire_target_h_payto, + &bd.merchant_pub, + "x-bank", + &wtid2, + &total2)); + FAILIF (0 != + GNUNET_memcmp (&wtid2, + &wtid)); + FAILIF (0 != + TALER_amount_cmp (&total2, + &total)); + FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + plugin->delete_aggregation_transient (plugin->cls, + &wire_target_h_payto, + &wtid)); + FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != + plugin->select_aggregation_transient (plugin->cls, + &wire_target_h_payto, + &bd.merchant_pub, + "x-bank", + &wtid2, + &total2)); + } FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != plugin->commit (plugin->cls)); result = 10; - deposit2 = deposit; FAILIF (GNUNET_OK != plugin->start (plugin->cls, "test-2")); - RND_BLK (&deposit2.merchant_pub); /* should fail if merchant is different */ + RND_BLK (&mpub2); /* should fail if merchant is different */ { - struct TALER_MerchantWireHash h_wire; + struct TALER_MerchantWireHashP h_wire; struct GNUNET_TIME_Timestamp r; struct TALER_Amount deposit_fee; - TALER_merchant_wire_signature_hash (deposit2.receiver_wire_account, - &deposit2.wire_salt, + TALER_merchant_wire_signature_hash (bd.receiver_wire_account, + &bd.wire_salt, &h_wire); FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != plugin->have_deposit2 (plugin->cls, - &deposit2.h_contract_terms, + &bd.h_contract_terms, &h_wire, - &deposit2.coin.coin_pub, - &deposit2.merchant_pub, - deposit2.refund_deadline, + &deposit.coin.coin_pub, + &mpub2, + bd.refund_deadline, &deposit_fee, &r)); - deposit2.merchant_pub = deposit.merchant_pub; - RND_BLK (&deposit2.coin.coin_pub); /* should fail if coin is different */ + RND_BLK (&cpub2); /* should fail if coin is different */ FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != plugin->have_deposit2 (plugin->cls, - &deposit2.h_contract_terms, + &bd.h_contract_terms, &h_wire, - &deposit2.coin.coin_pub, - &deposit2.merchant_pub, - deposit2.refund_deadline, + &cpub2, + &bd.merchant_pub, + bd.refund_deadline, &deposit_fee, &r)); } @@ -2251,6 +2369,9 @@ run (void *cls) /* test revocation */ + FAILIF (GNUNET_OK != + plugin->start (plugin->cls, + "test-3b")); RND_BLK (&master_sig); FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->insert_denomination_revocation (plugin->cls, @@ -2289,7 +2410,7 @@ run (void *cls) FAILIF (GNUNET_OK != test_wire_prepare ()); FAILIF (GNUNET_OK != - test_wire_out (&deposit)); + test_wire_out (&bd)); FAILIF (GNUNET_OK != test_gc ()); FAILIF (GNUNET_OK != @@ -2308,6 +2429,7 @@ drop: rh = NULL; GNUNET_break (GNUNET_OK == plugin->drop_tables (plugin->cls)); +cleanup: if (NULL != dkp) destroy_denom_key_pair (dkp); if (NULL != revealed_coins) @@ -2315,7 +2437,7 @@ drop: for (unsigned int cnt = 0; cnt < MELT_NEW_COINS; cnt++) { TALER_blinded_denom_sig_free (&revealed_coins[cnt].coin_sig); - GNUNET_free (revealed_coins[cnt].coin_ev); + TALER_blinded_planchet_free (&revealed_coins[cnt].blinded_planchet); } GNUNET_free (revealed_coins); revealed_coins = NULL; @@ -2352,8 +2474,9 @@ main (int argc, return -1; } GNUNET_log_setup (argv[0], - "WARNING", + "INFO", NULL); + TALER_OS_init (); plugin_name++; (void) GNUNET_asprintf (&testname, "test-exchange-db-%s", |