Compare commits
5 Commits
eccf37e450
...
4a03a20a04
Author | SHA1 | Date | |
---|---|---|---|
4a03a20a04 | |||
![]() |
007e4bc954 | ||
![]() |
bad572a010 | ||
![]() |
8da74a6ca7 | ||
![]() |
f6a7d4a1ed |
@ -1 +1 @@
|
||||
1655124520
|
||||
1655640402
|
||||
|
@ -113,7 +113,7 @@ currency = TESTKUDOS
|
||||
[merchant-exchange-default]
|
||||
CURRENCY = TESTKUDOS
|
||||
EXCHANGE_BASE_URL = http://localhost:8081/
|
||||
MASTER_KEY = GPB1CSPV6E49MET2PX6BFWVBGFF8BAE14M05RJB54C28EY1HX42G
|
||||
MASTER_KEY = JM0NJXHM6Y6HYAPK2WDFH3HDJ2E9KZWGKM3E0FYRV2V3HCTB3DQ0
|
||||
|
||||
[merchant-account-merchant]
|
||||
ACTIVE_default = YES
|
||||
@ -157,7 +157,7 @@ CONFIG = postgres:///auditor-basedb
|
||||
[exchange]
|
||||
LOOKAHEAD_SIGN = 32 weeks 1 day
|
||||
SIGNKEY_DURATION = 4 weeks
|
||||
MASTER_PUBLIC_KEY = GPB1CSPV6E49MET2PX6BFWVBGFF8BAE14M05RJB54C28EY1HX42G
|
||||
MASTER_PUBLIC_KEY = JM0NJXHM6Y6HYAPK2WDFH3HDJ2E9KZWGKM3E0FYRV2V3HCTB3DQ0
|
||||
SIGNKEY_LEGAL_DURATION = 4 weeks
|
||||
UNIXPATH = ${TALER_RUNTIME_DIR}/exchange.http
|
||||
|
||||
@ -175,7 +175,7 @@ DATABASE = postgres:///auditor-basedb
|
||||
CONFIG = postgres:///auditor-basedb
|
||||
|
||||
[auditor]
|
||||
PUBLIC_KEY = FBVV6V14GCCR95X2W2PMCBTFYZ4S3SX3JN504M8SJTMK1JBBV99G
|
||||
PUBLIC_KEY = 73NJKBP4MHJF8274K88F4WFWKNYMK8T6MTSE6HHYS6WC01H9YH7G
|
||||
TINY_AMOUNT = TESTKUDOS:0.01
|
||||
BASE_URL = http://localhost:8083/
|
||||
|
||||
|
@ -1 +1 @@
|
||||
GPB1CSPV6E49MET2PX6BFWVBGFF8BAE14M05RJB54C28EY1HX42G
|
||||
JM0NJXHM6Y6HYAPK2WDFH3HDJ2E9KZWGKM3E0FYRV2V3HCTB3DQ0
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1 +1 @@
|
||||
1655124599
|
||||
1655640625
|
||||
|
@ -1 +1 @@
|
||||
6CF031C2JWXQB98SNHARWSPJMYR8JM26BVDV08CPH63T2M9JXV30
|
||||
MREDG0XYVSX4RPYSA6JNQZ93P2DDBG45F3M6RBZXRS49M0JTVN40
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2350,6 +2350,11 @@ check_denomination (
|
||||
* @param cls closure
|
||||
* @param rowid unique serial ID for the deposit in our DB
|
||||
* @param deposit deposit details
|
||||
* @param reserve_pub which reserve is the purse merged into, NULL if unknown
|
||||
* @param flags purse flags
|
||||
* @param auditor_balance purse balance (according to the
|
||||
* auditor during auditing)
|
||||
* @param purse_total target amount the purse should reach
|
||||
* @param denom_pub denomination public key of @a coin_pub
|
||||
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
|
||||
*/
|
||||
@ -2358,6 +2363,10 @@ purse_deposit_cb (
|
||||
void *cls,
|
||||
uint64_t rowid,
|
||||
const struct TALER_EXCHANGEDB_PurseDeposit *deposit,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
enum TALER_WalletAccountMergeFlags flags,
|
||||
const struct TALER_Amount *auditor_balance,
|
||||
const struct TALER_Amount *purse_total,
|
||||
const struct TALER_DenominationPublicKey *denom_pub)
|
||||
{
|
||||
struct CoinContext *cc = cls;
|
||||
@ -2366,6 +2375,10 @@ purse_deposit_cb (
|
||||
const struct TALER_EXCHANGEDB_DenominationKeyInformation *issue;
|
||||
struct DenominationSummary *ds;
|
||||
|
||||
(void) flags;
|
||||
(void) auditor_balance;
|
||||
(void) purse_total;
|
||||
(void) reserve_pub;
|
||||
GNUNET_assert (rowid >= ppc.last_purse_deposits_serial_id);
|
||||
ppc.last_purse_deposits_serial_id = rowid + 1;
|
||||
qs = TALER_ARL_get_denomination_info (denom_pub,
|
||||
|
@ -69,6 +69,11 @@ static json_t *denomination_key_validity_withdraw_inconsistencies;
|
||||
*/
|
||||
static json_t *report_reserve_balance_insufficient_inconsistencies;
|
||||
|
||||
/**
|
||||
* Array of reports about purse balance insufficient inconsitencies.
|
||||
*/
|
||||
static json_t *report_purse_balance_insufficient_inconsistencies;
|
||||
|
||||
/**
|
||||
* Total amount reserves were charged beyond their balance.
|
||||
*/
|
||||
@ -399,6 +404,54 @@ struct ReserveContext
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create a new reserve for @a reserve_pub in @a rc.
|
||||
*
|
||||
* @param[in,out] rc context to update
|
||||
* @param reserve_pub key for which to create a reserve
|
||||
* @return NULL on error
|
||||
*/
|
||||
static struct ReserveSummary *
|
||||
setup_reserve (struct ReserveContext *rc,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub)
|
||||
{
|
||||
struct ReserveSummary *rs;
|
||||
struct GNUNET_HashCode key;
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
|
||||
GNUNET_CRYPTO_hash (reserve_pub,
|
||||
sizeof (*reserve_pub),
|
||||
&key);
|
||||
rs = GNUNET_CONTAINER_multihashmap_get (rc->reserves,
|
||||
&key);
|
||||
if (NULL != rs)
|
||||
return rs;
|
||||
rs = GNUNET_new (struct ReserveSummary);
|
||||
rs->reserve_pub = *reserve_pub;
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_amount_set_zero (TALER_ARL_currency,
|
||||
&rs->total_in));
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_amount_set_zero (TALER_ARL_currency,
|
||||
&rs->total_out));
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_amount_set_zero (TALER_ARL_currency,
|
||||
&rs->total_fee));
|
||||
if (0 > (qs = load_auditor_reserve_summary (rs)))
|
||||
{
|
||||
GNUNET_free (rs);
|
||||
rc->qs = qs;
|
||||
return NULL;
|
||||
}
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
GNUNET_CONTAINER_multihashmap_put (rc->reserves,
|
||||
&key,
|
||||
rs,
|
||||
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
|
||||
return rs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function called with details about incoming wire transfers.
|
||||
*
|
||||
@ -421,54 +474,26 @@ handle_reserve_in (void *cls,
|
||||
struct GNUNET_TIME_Timestamp execution_date)
|
||||
{
|
||||
struct ReserveContext *rc = cls;
|
||||
struct GNUNET_HashCode key;
|
||||
struct ReserveSummary *rs;
|
||||
struct GNUNET_TIME_Timestamp expiry;
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
|
||||
(void) wire_reference;
|
||||
/* should be monotonically increasing */
|
||||
GNUNET_assert (rowid >= ppr.last_reserve_in_serial_id);
|
||||
ppr.last_reserve_in_serial_id = rowid + 1;
|
||||
|
||||
GNUNET_CRYPTO_hash (reserve_pub,
|
||||
sizeof (*reserve_pub),
|
||||
&key);
|
||||
rs = GNUNET_CONTAINER_multihashmap_get (rc->reserves,
|
||||
&key);
|
||||
rs = setup_reserve (rc,
|
||||
reserve_pub);
|
||||
if (NULL == rs)
|
||||
{
|
||||
rs = GNUNET_new (struct ReserveSummary);
|
||||
GNUNET_break (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
TALER_ARL_amount_add (&rs->total_in,
|
||||
&rs->total_in,
|
||||
credit);
|
||||
if (NULL == rs->sender_account)
|
||||
rs->sender_account = GNUNET_strdup (sender_account_details);
|
||||
rs->reserve_pub = *reserve_pub;
|
||||
rs->total_in = *credit;
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_amount_set_zero (credit->currency,
|
||||
&rs->total_out));
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_amount_set_zero (credit->currency,
|
||||
&rs->total_fee));
|
||||
if (0 > (qs = load_auditor_reserve_summary (rs)))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
GNUNET_free (rs);
|
||||
rc->qs = qs;
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
GNUNET_CONTAINER_multihashmap_put (rc->reserves,
|
||||
&key,
|
||||
rs,
|
||||
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
|
||||
}
|
||||
else
|
||||
{
|
||||
TALER_ARL_amount_add (&rs->total_in,
|
||||
&rs->total_in,
|
||||
credit);
|
||||
if (NULL == rs->sender_account)
|
||||
rs->sender_account = GNUNET_strdup (sender_account_details);
|
||||
}
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||
"Additional incoming wire transfer for reserve `%s' of %s\n",
|
||||
TALER_B2S (reserve_pub),
|
||||
@ -509,7 +534,6 @@ handle_reserve_out (void *cls,
|
||||
const struct TALER_Amount *amount_with_fee)
|
||||
{
|
||||
struct ReserveContext *rc = cls;
|
||||
struct GNUNET_HashCode key;
|
||||
struct ReserveSummary *rs;
|
||||
const struct TALER_EXCHANGEDB_DenominationKeyInformation *issue;
|
||||
struct TALER_Amount auditor_amount_with_fee;
|
||||
@ -608,44 +632,16 @@ handle_reserve_out (void *cls,
|
||||
rowid,
|
||||
"amount with fee from exchange does not match denomination value plus fee");
|
||||
}
|
||||
|
||||
|
||||
GNUNET_CRYPTO_hash (reserve_pub,
|
||||
sizeof (*reserve_pub),
|
||||
&key);
|
||||
rs = GNUNET_CONTAINER_multihashmap_get (rc->reserves,
|
||||
&key);
|
||||
rs = setup_reserve (rc,
|
||||
reserve_pub);
|
||||
if (NULL == rs)
|
||||
{
|
||||
rs = GNUNET_new (struct ReserveSummary);
|
||||
rs->reserve_pub = *reserve_pub;
|
||||
rs->total_out = auditor_amount_with_fee;
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_amount_set_zero (amount_with_fee->currency,
|
||||
&rs->total_in));
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_amount_set_zero (amount_with_fee->currency,
|
||||
&rs->total_fee));
|
||||
qs = load_auditor_reserve_summary (rs);
|
||||
if (0 > qs)
|
||||
{
|
||||
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
||||
GNUNET_free (rs);
|
||||
rc->qs = qs;
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
GNUNET_CONTAINER_multihashmap_put (rc->reserves,
|
||||
&key,
|
||||
rs,
|
||||
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
|
||||
}
|
||||
else
|
||||
{
|
||||
TALER_ARL_amount_add (&rs->total_out,
|
||||
&rs->total_out,
|
||||
&auditor_amount_with_fee);
|
||||
GNUNET_break (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
TALER_ARL_amount_add (&rs->total_out,
|
||||
&rs->total_out,
|
||||
&auditor_amount_with_fee);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||
"Reserve `%s' reduced by %s from withdraw\n",
|
||||
TALER_B2S (reserve_pub),
|
||||
@ -691,7 +687,6 @@ handle_recoup_by_reserve (
|
||||
const union TALER_DenominationBlindingKeyP *coin_blind)
|
||||
{
|
||||
struct ReserveContext *rc = cls;
|
||||
struct GNUNET_HashCode key;
|
||||
struct ReserveSummary *rs;
|
||||
struct GNUNET_TIME_Timestamp expiry;
|
||||
struct TALER_MasterSignatureP msig;
|
||||
@ -764,12 +759,13 @@ handle_recoup_by_reserve (
|
||||
{
|
||||
rev = "revoked";
|
||||
}
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
GNUNET_CONTAINER_multihashmap_put (rc->revoked,
|
||||
&coin->denom_pub_hash.
|
||||
hash,
|
||||
(void *) rev,
|
||||
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
|
||||
GNUNET_assert (
|
||||
GNUNET_OK ==
|
||||
GNUNET_CONTAINER_multihashmap_put (
|
||||
rc->revoked,
|
||||
&coin->denom_pub_hash.hash,
|
||||
(void *) rev,
|
||||
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -794,42 +790,16 @@ handle_recoup_by_reserve (
|
||||
amount);
|
||||
}
|
||||
|
||||
GNUNET_CRYPTO_hash (reserve_pub,
|
||||
sizeof (*reserve_pub),
|
||||
&key);
|
||||
rs = GNUNET_CONTAINER_multihashmap_get (rc->reserves,
|
||||
&key);
|
||||
rs = setup_reserve (rc,
|
||||
reserve_pub);
|
||||
if (NULL == rs)
|
||||
{
|
||||
rs = GNUNET_new (struct ReserveSummary);
|
||||
rs->reserve_pub = *reserve_pub;
|
||||
rs->total_in = *amount;
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_amount_set_zero (amount->currency,
|
||||
&rs->total_out));
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_amount_set_zero (amount->currency,
|
||||
&rs->total_fee));
|
||||
qs = load_auditor_reserve_summary (rs);
|
||||
if (0 > qs)
|
||||
{
|
||||
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
||||
GNUNET_free (rs);
|
||||
rc->qs = qs;
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
GNUNET_CONTAINER_multihashmap_put (rc->reserves,
|
||||
&key,
|
||||
rs,
|
||||
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
|
||||
}
|
||||
else
|
||||
{
|
||||
TALER_ARL_amount_add (&rs->total_in,
|
||||
&rs->total_in,
|
||||
amount);
|
||||
GNUNET_break (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
TALER_ARL_amount_add (&rs->total_in,
|
||||
&rs->total_in,
|
||||
amount);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||
"Additional /recoup value to for reserve `%s' of %s\n",
|
||||
TALER_B2S (reserve_pub),
|
||||
@ -923,44 +893,20 @@ handle_reserve_closed (
|
||||
const struct TALER_WireTransferIdentifierRawP *transfer_details)
|
||||
{
|
||||
struct ReserveContext *rc = cls;
|
||||
struct GNUNET_HashCode key;
|
||||
struct ReserveSummary *rs;
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
|
||||
(void) transfer_details;
|
||||
/* should be monotonically increasing */
|
||||
GNUNET_assert (rowid >= ppr.last_reserve_close_serial_id);
|
||||
ppr.last_reserve_close_serial_id = rowid + 1;
|
||||
|
||||
GNUNET_CRYPTO_hash (reserve_pub,
|
||||
sizeof (*reserve_pub),
|
||||
&key);
|
||||
rs = GNUNET_CONTAINER_multihashmap_get (rc->reserves,
|
||||
&key);
|
||||
rs = setup_reserve (rc,
|
||||
reserve_pub);
|
||||
if (NULL == rs)
|
||||
{
|
||||
rs = GNUNET_new (struct ReserveSummary);
|
||||
rs->reserve_pub = *reserve_pub;
|
||||
rs->total_out = *amount_with_fee;
|
||||
rs->total_fee = *closing_fee;
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_amount_set_zero (amount_with_fee->currency,
|
||||
&rs->total_in));
|
||||
qs = load_auditor_reserve_summary (rs);
|
||||
if (0 > qs)
|
||||
{
|
||||
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
||||
GNUNET_free (rs);
|
||||
rc->qs = qs;
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
GNUNET_CONTAINER_multihashmap_put (rc->reserves,
|
||||
&key,
|
||||
rs,
|
||||
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
|
||||
GNUNET_break (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct TALER_Amount expected_fee;
|
||||
|
||||
@ -1088,7 +1034,7 @@ verify_reserve_balance (void *cls,
|
||||
making an illegitimate gain over the amount it dropped.
|
||||
We don't add the amount to some total simply because it is
|
||||
not an actualized gain and could be trivially corrected by
|
||||
restoring the summary. *///
|
||||
restoring the summary. */
|
||||
TALER_ARL_report (report_reserve_balance_insufficient_inconsistencies,
|
||||
GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_data_auto ("reserve_pub",
|
||||
@ -1315,6 +1261,12 @@ verify_reserve_balance (void *cls,
|
||||
* @param cls closure
|
||||
* @param rowid unique serial ID for the deposit in our DB
|
||||
* @param deposit deposit details
|
||||
* @param reserve_pub which reserve is the purse merged into, NULL if unknown
|
||||
* @param auditor_balance balance of the purse calculated by auditor
|
||||
* @param flags purse flags
|
||||
* @param auditor_balance purse balance (according to the
|
||||
* auditor during auditing)
|
||||
* @param purse_total target amount the purse should reach
|
||||
* @param denom_pub denomination public key of @a coin_pub
|
||||
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
|
||||
*/
|
||||
@ -1323,11 +1275,130 @@ handle_purse_deposits (
|
||||
void *cls,
|
||||
uint64_t rowid,
|
||||
const struct TALER_EXCHANGEDB_PurseDeposit *deposit,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
enum TALER_WalletAccountMergeFlags flags,
|
||||
const struct TALER_Amount *auditor_balance,
|
||||
const struct TALER_Amount *purse_total,
|
||||
const struct TALER_DenominationPublicKey *denom_pub)
|
||||
{
|
||||
GNUNET_break (0); // FIXME
|
||||
/* Credit purse value (if last op)! */
|
||||
return GNUNET_SYSERR;
|
||||
struct ReserveContext *rc = cls;
|
||||
const char *base_url
|
||||
= (NULL == deposit->exchange_base_url)
|
||||
? TALER_ARL_exchange_url
|
||||
: deposit->exchange_base_url;
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
struct TALER_Amount amount_minus_fee;
|
||||
struct TALER_Amount new_balance;
|
||||
struct ReserveSummary *rs;
|
||||
|
||||
/* should be monotonically increasing */
|
||||
GNUNET_assert (rowid >= ppr.last_purse_deposits_serial_id);
|
||||
ppr.last_purse_deposits_serial_id = rowid + 1;
|
||||
|
||||
if (GNUNET_OK !=
|
||||
TALER_wallet_purse_deposit_verify (base_url,
|
||||
&deposit->purse_pub,
|
||||
&deposit->amount,
|
||||
&deposit->coin_pub,
|
||||
&deposit->coin_sig))
|
||||
{
|
||||
TALER_ARL_report (report_bad_sig_losses,
|
||||
GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_string ("operation",
|
||||
"purse-deposit"),
|
||||
GNUNET_JSON_pack_uint64 ("row",
|
||||
rowid),
|
||||
TALER_JSON_pack_amount ("loss",
|
||||
&deposit->amount),
|
||||
GNUNET_JSON_pack_data_auto ("key_pub",
|
||||
&deposit->coin_pub)));
|
||||
TALER_ARL_amount_add (&total_bad_sig_loss,
|
||||
&total_bad_sig_loss,
|
||||
&deposit->amount);
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
{
|
||||
const struct TALER_EXCHANGEDB_DenominationKeyInformation *issue;
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
struct TALER_DenominationHashP h_denom_pub;
|
||||
|
||||
qs = TALER_ARL_get_denomination_info (denom_pub,
|
||||
&issue,
|
||||
&h_denom_pub);
|
||||
if (0 > qs)
|
||||
{
|
||||
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
||||
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Hard database error trying to get denomination %s from database!\n",
|
||||
TALER_B2S (denom_pub));
|
||||
rc->qs = qs;
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
|
||||
{
|
||||
report_row_inconsistency ("purse-deposit",
|
||||
rowid,
|
||||
"denomination key not found");
|
||||
if (TALER_ARL_do_abort ())
|
||||
return GNUNET_SYSERR;
|
||||
return GNUNET_OK;
|
||||
}
|
||||
TALER_ARL_amount_subtract (&amount_minus_fee,
|
||||
&deposit->amount,
|
||||
&issue->fees.deposit);
|
||||
}
|
||||
|
||||
TALER_ARL_amount_add (&new_balance,
|
||||
auditor_balance,
|
||||
&amount_minus_fee);
|
||||
qs = TALER_ARL_edb->set_purse_balance (TALER_ARL_edb->cls,
|
||||
&deposit->purse_pub,
|
||||
&new_balance);
|
||||
GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs);
|
||||
if (qs < 0)
|
||||
{
|
||||
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
||||
GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
|
||||
rc->qs = qs;
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if (TALER_WAMF_MODE_CREATE_WITH_PURSE_FEE !=
|
||||
(flags & TALER_WAMF_MERGE_MODE_MASK))
|
||||
{
|
||||
/* This just created the purse, actual credit to
|
||||
the reserve will be done in handle_account_merged() */
|
||||
return GNUNET_OK;
|
||||
}
|
||||
if ( (NULL != deposit->exchange_base_url) &&
|
||||
(0 != strcmp (deposit->exchange_base_url,
|
||||
TALER_ARL_exchange_url)) )
|
||||
{
|
||||
/* credited reserve is at another exchange, do NOT credit here! */
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
rs = setup_reserve (rc,
|
||||
reserve_pub);
|
||||
if (NULL == rs)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if ( (-1 != TALER_amount_cmp (&new_balance,
|
||||
purse_total)) &&
|
||||
(-1 == TALER_amount_cmp (auditor_balance,
|
||||
purse_total)) )
|
||||
{
|
||||
/* new balance at or above purse_total
|
||||
(and previous balance was below); thus
|
||||
credit reserve with purse value! */
|
||||
TALER_ARL_amount_add (&rs->total_in,
|
||||
&rs->total_in,
|
||||
purse_total);
|
||||
}
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -1338,6 +1409,15 @@ handle_purse_deposits (
|
||||
*
|
||||
* @param cls closure
|
||||
* @param rowid unique serial ID for the deposit in our DB
|
||||
* @param partner_base_url where is the reserve, NULL for this exchange
|
||||
* @param amount total amount expected in the purse
|
||||
* @param balance current balance in the purse (according to the auditor)
|
||||
* @param flags purse flags
|
||||
* @param merge_pub merge capability key
|
||||
* @param reserve_pub reserve the merge affects
|
||||
* @param merge_sig signature affirming the merge
|
||||
* @param purse_pub purse key
|
||||
* @param merge_timestamp when did the merge happen
|
||||
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
|
||||
*/
|
||||
static enum GNUNET_GenericReturnValue
|
||||
@ -1346,6 +1426,7 @@ handle_purse_merged (
|
||||
uint64_t rowid,
|
||||
const char *partner_base_url,
|
||||
const struct TALER_Amount *amount,
|
||||
const struct TALER_Amount *balance,
|
||||
enum TALER_WalletAccountMergeFlags flags,
|
||||
const struct TALER_PurseMergePublicKeyP *merge_pub,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
@ -1353,9 +1434,92 @@ handle_purse_merged (
|
||||
const struct TALER_PurseContractPublicKeyP *purse_pub,
|
||||
struct GNUNET_TIME_Timestamp merge_timestamp)
|
||||
{
|
||||
GNUNET_break (0); // FIXME
|
||||
/* Credit purse value (if last op)! */
|
||||
return GNUNET_SYSERR;
|
||||
struct ReserveContext *rc = cls;
|
||||
struct ReserveSummary *rs;
|
||||
char *reserve_url;
|
||||
|
||||
/* should be monotonically increasing */
|
||||
GNUNET_assert (rowid >= ppr.last_purse_merges_serial_id);
|
||||
ppr.last_purse_merges_serial_id = rowid + 1;
|
||||
reserve_url
|
||||
= TALER_reserve_make_payto (NULL == partner_base_url
|
||||
? TALER_ARL_exchange_url
|
||||
: partner_base_url,
|
||||
reserve_pub);
|
||||
if (GNUNET_OK !=
|
||||
TALER_wallet_purse_merge_verify (reserve_url,
|
||||
merge_timestamp,
|
||||
purse_pub,
|
||||
merge_pub,
|
||||
merge_sig))
|
||||
{
|
||||
GNUNET_free (reserve_url);
|
||||
TALER_ARL_report (report_bad_sig_losses,
|
||||
GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_string ("operation",
|
||||
"merge-purse"),
|
||||
GNUNET_JSON_pack_uint64 ("row",
|
||||
rowid),
|
||||
TALER_JSON_pack_amount ("loss",
|
||||
amount),
|
||||
GNUNET_JSON_pack_data_auto ("key_pub",
|
||||
merge_pub)));
|
||||
TALER_ARL_amount_add (&total_bad_sig_loss,
|
||||
&total_bad_sig_loss,
|
||||
amount);
|
||||
return GNUNET_OK;
|
||||
}
|
||||
GNUNET_free (reserve_url);
|
||||
if (TALER_WAMF_MODE_CREATE_WITH_PURSE_FEE ==
|
||||
(flags & TALER_WAMF_MERGE_MODE_MASK))
|
||||
{
|
||||
/* This just created the purse, actual credit to
|
||||
the reserve will be done in handle_purse_deposits() */
|
||||
return GNUNET_OK;
|
||||
}
|
||||
if ( (NULL != partner_base_url) &&
|
||||
(0 != strcmp (partner_base_url,
|
||||
TALER_ARL_exchange_url)) )
|
||||
{
|
||||
/* credited reserve is at another exchange, do NOT credit here! */
|
||||
return GNUNET_OK;
|
||||
}
|
||||
rs = setup_reserve (rc,
|
||||
reserve_pub);
|
||||
if (NULL == rs)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if (-1 == TALER_amount_cmp (balance,
|
||||
amount))
|
||||
{
|
||||
struct TALER_Amount loss;
|
||||
|
||||
TALER_ARL_amount_subtract (&loss,
|
||||
amount,
|
||||
balance);
|
||||
/* illegal merge, balance is still below total purse value */
|
||||
TALER_ARL_report (report_purse_balance_insufficient_inconsistencies,
|
||||
GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_string ("operation",
|
||||
"merge-purse"),
|
||||
GNUNET_JSON_pack_uint64 ("row",
|
||||
rowid),
|
||||
TALER_JSON_pack_amount ("loss",
|
||||
&loss),
|
||||
GNUNET_JSON_pack_data_auto ("purse_pub",
|
||||
purse_pub)));
|
||||
TALER_ARL_amount_add (&total_balance_insufficient_loss,
|
||||
&total_balance_insufficient_loss,
|
||||
&loss);
|
||||
return GNUNET_OK;
|
||||
}
|
||||
TALER_ARL_amount_add (&rs->total_in,
|
||||
&rs->total_in,
|
||||
amount);
|
||||
// rs->a_expiration_date = FIXME: do we care? If so, set to what (so that the auditor no longer complains about the reserve not being closed)
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -1381,11 +1545,55 @@ handle_account_merged (
|
||||
enum TALER_WalletAccountMergeFlags flags,
|
||||
const struct TALER_Amount *purse_fee,
|
||||
struct GNUNET_TIME_Timestamp merge_timestamp,
|
||||
struct TALER_ReserveSignatureP *reserve_sig)
|
||||
const struct TALER_ReserveSignatureP *reserve_sig)
|
||||
{
|
||||
GNUNET_break (0); // FIXME
|
||||
/* Debit purse fee */
|
||||
return GNUNET_SYSERR;
|
||||
struct ReserveContext *rc = cls;
|
||||
struct ReserveSummary *rs;
|
||||
|
||||
/* should be monotonically increasing */
|
||||
GNUNET_assert (rowid >= ppr.last_account_merges_serial_id);
|
||||
ppr.last_account_merges_serial_id = rowid + 1;
|
||||
if (GNUNET_OK !=
|
||||
TALER_wallet_account_merge_verify (merge_timestamp,
|
||||
purse_pub,
|
||||
purse_expiration,
|
||||
h_contract_terms,
|
||||
amount,
|
||||
purse_fee,
|
||||
min_age,
|
||||
flags,
|
||||
reserve_pub,
|
||||
reserve_sig))
|
||||
{
|
||||
TALER_ARL_report (report_bad_sig_losses,
|
||||
GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_string ("operation",
|
||||
"account-merge"),
|
||||
GNUNET_JSON_pack_uint64 ("row",
|
||||
rowid),
|
||||
TALER_JSON_pack_amount ("loss",
|
||||
purse_fee),
|
||||
GNUNET_JSON_pack_data_auto ("key_pub",
|
||||
reserve_pub)));
|
||||
TALER_ARL_amount_add (&total_bad_sig_loss,
|
||||
&total_bad_sig_loss,
|
||||
purse_fee);
|
||||
return GNUNET_OK;
|
||||
}
|
||||
rs = setup_reserve (rc,
|
||||
reserve_pub);
|
||||
if (NULL == rs)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
TALER_ARL_amount_add (&total_purse_fee_income,
|
||||
&total_purse_fee_income,
|
||||
purse_fee);
|
||||
TALER_ARL_amount_add (&rs->total_out,
|
||||
&rs->total_out,
|
||||
purse_fee);
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -1407,9 +1615,47 @@ handle_history_request (
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
const struct TALER_ReserveSignatureP *reserve_sig)
|
||||
{
|
||||
GNUNET_break (0); // FIXME
|
||||
/* Debit purse fee */
|
||||
return GNUNET_SYSERR;
|
||||
struct ReserveContext *rc = cls;
|
||||
struct ReserveSummary *rs;
|
||||
|
||||
/* should be monotonically increasing */
|
||||
GNUNET_assert (rowid >= ppr.last_history_requests_serial_id);
|
||||
ppr.last_history_requests_serial_id = rowid + 1;
|
||||
if (GNUNET_OK !=
|
||||
TALER_wallet_reserve_history_verify (ts,
|
||||
history_fee,
|
||||
reserve_pub,
|
||||
reserve_sig))
|
||||
{
|
||||
TALER_ARL_report (report_bad_sig_losses,
|
||||
GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_string ("operation",
|
||||
"account-history"),
|
||||
GNUNET_JSON_pack_uint64 ("row",
|
||||
rowid),
|
||||
TALER_JSON_pack_amount ("loss",
|
||||
history_fee),
|
||||
GNUNET_JSON_pack_data_auto ("key_pub",
|
||||
reserve_pub)));
|
||||
TALER_ARL_amount_add (&total_bad_sig_loss,
|
||||
&total_bad_sig_loss,
|
||||
history_fee);
|
||||
return GNUNET_OK;
|
||||
}
|
||||
rs = setup_reserve (rc,
|
||||
reserve_pub);
|
||||
if (NULL == rs)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
TALER_ARL_amount_add (&total_history_fee_income,
|
||||
&total_history_fee_income,
|
||||
history_fee);
|
||||
TALER_ARL_amount_add (&rs->total_out,
|
||||
&rs->total_out,
|
||||
history_fee);
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -1515,17 +1761,6 @@ analyze_reserves (void *cls)
|
||||
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
||||
return qs;
|
||||
}
|
||||
/* Credit purse value (if last op)! */
|
||||
qs = TALER_ARL_edb->select_purse_merges_above_serial_id (
|
||||
TALER_ARL_edb->cls,
|
||||
ppr.last_purse_merges_serial_id,
|
||||
&handle_purse_merged,
|
||||
&rc);
|
||||
if (qs < 0)
|
||||
{
|
||||
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
||||
return qs;
|
||||
}
|
||||
qs = TALER_ARL_edb->select_purse_deposits_above_serial_id (
|
||||
TALER_ARL_edb->cls,
|
||||
ppr.last_purse_deposits_serial_id,
|
||||
@ -1547,6 +1782,17 @@ analyze_reserves (void *cls)
|
||||
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
||||
return qs;
|
||||
}
|
||||
/* Credit purse value (if last op)! */
|
||||
qs = TALER_ARL_edb->select_purse_merges_above_serial_id (
|
||||
TALER_ARL_edb->cls,
|
||||
ppr.last_purse_merges_serial_id,
|
||||
&handle_purse_merged,
|
||||
&rc);
|
||||
if (qs < 0)
|
||||
{
|
||||
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
||||
return qs;
|
||||
}
|
||||
/* Charge history fee! */
|
||||
qs = TALER_ARL_edb->select_history_requests_above_serial_id (
|
||||
TALER_ARL_edb->cls,
|
||||
@ -1721,6 +1967,9 @@ run (void *cls,
|
||||
GNUNET_assert (NULL !=
|
||||
(report_reserve_balance_insufficient_inconsistencies
|
||||
= json_array ()));
|
||||
GNUNET_assert (NULL !=
|
||||
(report_purse_balance_insufficient_inconsistencies
|
||||
= json_array ()));
|
||||
GNUNET_assert (NULL !=
|
||||
(report_reserve_not_closed_inconsistencies
|
||||
= json_array ()));
|
||||
@ -1741,6 +1990,9 @@ run (void *cls,
|
||||
GNUNET_JSON_pack_array_steal (
|
||||
"reserve_balance_insufficient_inconsistencies",
|
||||
report_reserve_balance_insufficient_inconsistencies),
|
||||
GNUNET_JSON_pack_array_steal (
|
||||
"purse_balance_insufficient_inconsistencies",
|
||||
report_purse_balance_insufficient_inconsistencies),
|
||||
/* Tested in test-auditor.sh #3 */
|
||||
TALER_JSON_pack_amount ("total_loss_balance_insufficient",
|
||||
&total_balance_insufficient_loss),
|
||||
|
@ -220,8 +220,14 @@ run (void *cls)
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Test: insert_reserve_info\n");
|
||||
|
||||
struct TALER_Amount reserve_balance, withdraw_fee_balance;
|
||||
struct TALER_Amount reserve_balance2 = {}, withdraw_fee_balance2 = {};
|
||||
struct TALER_Amount reserve_balance;
|
||||
struct TALER_Amount withdraw_fee_balance;
|
||||
struct TALER_Amount purse_fee_balance;
|
||||
struct TALER_Amount history_fee_balance;
|
||||
struct TALER_Amount reserve_balance2 = {};
|
||||
struct TALER_Amount withdraw_fee_balance2 = {};
|
||||
struct TALER_Amount purse_fee_balance2 = {};
|
||||
struct TALER_Amount history_fee_balance2 = {};
|
||||
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_string_to_amount (CURRENCY ":12.345678",
|
||||
@ -229,6 +235,12 @@ run (void *cls)
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_string_to_amount (CURRENCY ":23.456789",
|
||||
&withdraw_fee_balance));
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_string_to_amount (CURRENCY ":23.456789",
|
||||
&purse_fee_balance));
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_string_to_amount (CURRENCY ":23.456789",
|
||||
&history_fee_balance));
|
||||
|
||||
|
||||
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
|
||||
@ -268,10 +280,12 @@ run (void *cls)
|
||||
FAILIF (0 != strcmp (payto,
|
||||
"payto://bla/blub"));
|
||||
GNUNET_free (payto);
|
||||
FAILIF (0 != GNUNET_memcmp (&date, &future)
|
||||
|| 0 != GNUNET_memcmp (&reserve_balance2, &reserve_balance)
|
||||
|| 0 != GNUNET_memcmp (&withdraw_fee_balance2,
|
||||
&withdraw_fee_balance));
|
||||
FAILIF (0 != GNUNET_memcmp (&date,
|
||||
&future)
|
||||
|| 0 != TALER_amount_cmp (&reserve_balance2,
|
||||
&reserve_balance)
|
||||
|| 0 != TALER_amount_cmp (&withdraw_fee_balance2,
|
||||
&withdraw_fee_balance));
|
||||
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Test: insert_reserve_summary\n");
|
||||
@ -279,8 +293,10 @@ run (void *cls)
|
||||
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
|
||||
plugin->insert_reserve_summary (plugin->cls,
|
||||
&master_pub,
|
||||
&reserve_balance,
|
||||
&withdraw_fee_balance,
|
||||
&reserve_balance));
|
||||
&purse_fee_balance,
|
||||
&history_fee_balance));
|
||||
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Test: update_reserve_summary\n");
|
||||
@ -289,25 +305,34 @@ run (void *cls)
|
||||
plugin->update_reserve_summary (plugin->cls,
|
||||
&master_pub,
|
||||
&reserve_balance,
|
||||
&withdraw_fee_balance));
|
||||
&withdraw_fee_balance,
|
||||
&purse_fee_balance,
|
||||
&history_fee_balance));
|
||||
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Test: get_reserve_summary\n");
|
||||
|
||||
ZR_BLK (&reserve_balance2);
|
||||
ZR_BLK (&withdraw_fee_balance2);
|
||||
ZR_BLK (&purse_fee_balance2);
|
||||
ZR_BLK (&history_fee_balance2);
|
||||
|
||||
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
|
||||
plugin->get_reserve_summary (plugin->cls,
|
||||
&master_pub,
|
||||
&reserve_balance2,
|
||||
&withdraw_fee_balance2));
|
||||
|
||||
FAILIF ( (0 != GNUNET_memcmp (&reserve_balance2,
|
||||
&reserve_balance) ||
|
||||
(0 != GNUNET_memcmp (&withdraw_fee_balance2,
|
||||
&withdraw_fee_balance)) ) );
|
||||
&withdraw_fee_balance2,
|
||||
&purse_fee_balance2,
|
||||
&history_fee_balance2));
|
||||
|
||||
FAILIF ( (0 != TALER_amount_cmp (&reserve_balance2,
|
||||
&reserve_balance) ||
|
||||
(0 != TALER_amount_cmp (&withdraw_fee_balance2,
|
||||
&withdraw_fee_balance)) ||
|
||||
(0 != TALER_amount_cmp (&purse_fee_balance2,
|
||||
&purse_fee_balance)) ||
|
||||
(0 != TALER_amount_cmp (&history_fee_balance2,
|
||||
&history_fee_balance))));
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Test: insert_denomination_balance\n");
|
||||
|
||||
|
@ -283,7 +283,6 @@ struct SigningKey
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct TEH_KeyStateHandle
|
||||
{
|
||||
|
||||
@ -404,7 +403,6 @@ struct SuspendedKeysRequests
|
||||
struct GNUNET_TIME_Absolute timeout;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Stores the latest generation of our key state.
|
||||
*/
|
||||
@ -1353,7 +1351,7 @@ denomination_info_cb (
|
||||
dk->meta = *meta;
|
||||
dk->master_sig = *master_sig;
|
||||
dk->recoup_possible = recoup_possible;
|
||||
dk->denom_pub.age_mask = meta->age_mask;
|
||||
dk->denom_pub.age_mask = meta->age_mask; /* FIXME-oec: age_mask -> reserved_field */
|
||||
|
||||
GNUNET_assert (
|
||||
GNUNET_OK ==
|
||||
@ -1361,6 +1359,7 @@ denomination_info_cb (
|
||||
&dk->h_denom_pub.hash,
|
||||
dk,
|
||||
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1727,12 +1726,12 @@ setup_general_response_headers (struct TEH_KeyStateHandle *ksh,
|
||||
* @a recoup and @a denoms.
|
||||
*
|
||||
* @param[in,out] ksh key state handle we build @a krd for
|
||||
* @param[in] denom_keys_hash hash over all the denominatoin keys in @a denoms and age_restricted_denoms
|
||||
* @param[in] denom_keys_hash hash over all the denominatoin keys in @a denoms
|
||||
* @param last_cpd timestamp to use
|
||||
* @param signkeys list of sign keys to return
|
||||
* @param recoup list of revoked keys to return
|
||||
* @param denoms list of denominations to return
|
||||
* @param age_restricted_denoms list of age restricted denominations to return, can be NULL
|
||||
* @param grouped_denominations list of grouped denominations to return
|
||||
* @return #GNUNET_OK on success
|
||||
*/
|
||||
static enum GNUNET_GenericReturnValue
|
||||
@ -1742,7 +1741,7 @@ create_krd (struct TEH_KeyStateHandle *ksh,
|
||||
json_t *signkeys,
|
||||
json_t *recoup,
|
||||
json_t *denoms,
|
||||
json_t *age_restricted_denoms)
|
||||
json_t *grouped_denominations)
|
||||
{
|
||||
struct KeysResponseData krd;
|
||||
struct TALER_ExchangePublicKeyP exchange_pub;
|
||||
@ -1753,6 +1752,7 @@ create_krd (struct TEH_KeyStateHandle *ksh,
|
||||
GNUNET_assert (NULL != signkeys);
|
||||
GNUNET_assert (NULL != recoup);
|
||||
GNUNET_assert (NULL != denoms);
|
||||
GNUNET_assert (NULL != grouped_denominations);
|
||||
GNUNET_assert (NULL != ksh->auditors);
|
||||
GNUNET_assert (NULL != TEH_currency);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
@ -1778,6 +1778,7 @@ create_krd (struct TEH_KeyStateHandle *ksh,
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const struct SigningKey *sk;
|
||||
|
||||
@ -1803,6 +1804,8 @@ create_krd (struct TEH_KeyStateHandle *ksh,
|
||||
recoup),
|
||||
GNUNET_JSON_pack_array_incref ("denoms",
|
||||
denoms),
|
||||
GNUNET_JSON_pack_array_incref ("denominations",
|
||||
grouped_denominations),
|
||||
GNUNET_JSON_pack_array_incref ("auditors",
|
||||
ksh->auditors),
|
||||
GNUNET_JSON_pack_array_incref ("global_fees",
|
||||
@ -1833,7 +1836,6 @@ create_krd (struct TEH_KeyStateHandle *ksh,
|
||||
{
|
||||
json_t *extensions = json_object ();
|
||||
bool has_extensions = false;
|
||||
bool age_restriction_enabled = false;
|
||||
|
||||
/* Fill in the configurations of the enabled extensions */
|
||||
for (const struct TALER_Extension *extension = TALER_extensions_get_head ();
|
||||
@ -1851,8 +1853,6 @@ create_krd (struct TEH_KeyStateHandle *ksh,
|
||||
|
||||
/* flag our findings so far */
|
||||
has_extensions = true;
|
||||
age_restriction_enabled = (extension->type ==
|
||||
TALER_Extension_AgeRestriction);
|
||||
|
||||
GNUNET_assert (NULL != extension->config_json);
|
||||
|
||||
@ -1901,20 +1901,6 @@ create_krd (struct TEH_KeyStateHandle *ksh,
|
||||
{
|
||||
json_decref (extensions);
|
||||
}
|
||||
|
||||
// Special case for age restrictions: if enabled, provide the list of
|
||||
// age-restricted denominations.
|
||||
if (age_restriction_enabled &&
|
||||
NULL != age_restricted_denoms)
|
||||
{
|
||||
GNUNET_assert (
|
||||
0 ==
|
||||
json_object_set (
|
||||
keys,
|
||||
"age_restricted_denoms",
|
||||
age_restricted_denoms));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -2010,12 +1996,10 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
|
||||
json_t *recoup;
|
||||
struct SignKeyCtx sctx;
|
||||
json_t *denoms = NULL;
|
||||
json_t *age_restricted_denoms = NULL;
|
||||
json_t *grouped_denominations = NULL;
|
||||
struct GNUNET_TIME_Timestamp last_cpd;
|
||||
struct GNUNET_CONTAINER_Heap *heap;
|
||||
struct GNUNET_HashContext *hash_context = NULL;
|
||||
struct GNUNET_HashContext *hash_context_restricted = NULL;
|
||||
bool have_age_restricted_denoms = false;
|
||||
|
||||
sctx.signkeys = json_array ();
|
||||
GNUNET_assert (NULL != sctx.signkeys);
|
||||
@ -2045,20 +2029,25 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
|
||||
GNUNET_assert (NULL != denoms);
|
||||
hash_context = GNUNET_CRYPTO_hash_context_start ();
|
||||
|
||||
/* If age restriction is enabled, initialize the array of age restricted
|
||||
denoms and prepare a hash for them, separate from the others. We will join
|
||||
those hashes afterwards.*/
|
||||
if (0)
|
||||
{
|
||||
age_restricted_denoms = json_array ();
|
||||
GNUNET_assert (NULL != age_restricted_denoms);
|
||||
hash_context_restricted = GNUNET_CRYPTO_hash_context_start ();
|
||||
}
|
||||
grouped_denominations = json_array ();
|
||||
GNUNET_assert (NULL != grouped_denominations);
|
||||
|
||||
last_cpd = GNUNET_TIME_UNIT_ZERO_TS;
|
||||
|
||||
{
|
||||
struct TEH_DenominationKey *dk;
|
||||
struct GNUNET_CONTAINER_MultiHashMap *denominations_by_group;
|
||||
|
||||
denominations_by_group =
|
||||
GNUNET_CONTAINER_multihashmap_create (1024,
|
||||
GNUNET_NO /* NO, because keys are only on the stack */);
|
||||
|
||||
/* groupData is the value we store for each group meta-data */
|
||||
struct groupData
|
||||
{
|
||||
json_t *json; /* The json blob with the group meta-data and list of denominations */
|
||||
struct GNUNET_HashContext *hash_context; /* hash over all denominations in that group */
|
||||
};
|
||||
|
||||
/* heap = min heap, sorted by start time */
|
||||
while (NULL != (dk = GNUNET_CONTAINER_heap_remove_root (heap)))
|
||||
@ -2068,12 +2057,12 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
|
||||
dk->meta.start) &&
|
||||
(! GNUNET_TIME_absolute_is_zero (last_cpd.abs_time)) )
|
||||
{
|
||||
struct GNUNET_HashCode hc;
|
||||
|
||||
/* FIXME-oec: Do we need to take hash_context_restricted into account
|
||||
* in this if-branch!? Current tests suggests: no, (they don't fail).
|
||||
* But something seems to be odd about only finishing hash_context.
|
||||
/*
|
||||
* This is not the first entry in the heap (because last_cpd !=
|
||||
* GNUNET_TIME_UNIT_ZERO_TS) and the previous entry had a different
|
||||
* start time. Therefore, we create an entry in the ksh.
|
||||
*/
|
||||
struct GNUNET_HashCode hc;
|
||||
|
||||
GNUNET_CRYPTO_hash_context_finish (
|
||||
GNUNET_CRYPTO_hash_context_copy (hash_context),
|
||||
@ -2085,7 +2074,7 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
|
||||
sctx.signkeys,
|
||||
recoup,
|
||||
denoms,
|
||||
age_restricted_denoms))
|
||||
grouped_denominations))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||
"Failed to generate key response data for %s\n",
|
||||
@ -2096,8 +2085,7 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
|
||||
/* intentionally empty */;
|
||||
GNUNET_CONTAINER_heap_destroy (heap);
|
||||
json_decref (denoms);
|
||||
if (NULL != age_restricted_denoms)
|
||||
json_decref (age_restricted_denoms);
|
||||
json_decref (grouped_denominations);
|
||||
json_decref (sctx.signkeys);
|
||||
json_decref (recoup);
|
||||
return GNUNET_SYSERR;
|
||||
@ -2108,9 +2096,6 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
|
||||
|
||||
{
|
||||
json_t *denom;
|
||||
json_t *array;
|
||||
struct GNUNET_HashContext *hc;
|
||||
|
||||
|
||||
denom =
|
||||
GNUNET_JSON_PACK (
|
||||
@ -2131,32 +2116,221 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
|
||||
TALER_JSON_PACK_DENOM_FEES ("fee",
|
||||
&dk->meta.fees));
|
||||
|
||||
/* Put the denom into the correct array depending on the settings and
|
||||
* the properties of the denomination. Also, we build up the right
|
||||
* hash for the corresponding array. */
|
||||
if (0 &&
|
||||
(0 != dk->denom_pub.age_mask.bits))
|
||||
{
|
||||
have_age_restricted_denoms = true;
|
||||
array = age_restricted_denoms;
|
||||
hc = hash_context_restricted;
|
||||
}
|
||||
else
|
||||
{
|
||||
array = denoms;
|
||||
hc = hash_context;
|
||||
}
|
||||
|
||||
GNUNET_CRYPTO_hash_context_read (hc,
|
||||
GNUNET_CRYPTO_hash_context_read (hash_context,
|
||||
&dk->h_denom_pub,
|
||||
sizeof (struct GNUNET_HashCode));
|
||||
|
||||
GNUNET_assert (
|
||||
0 ==
|
||||
json_array_append_new (
|
||||
array,
|
||||
denoms,
|
||||
denom));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Group the denominations by {cipher, value, fees, age_mask}.
|
||||
*
|
||||
* For each group we save the group meta-data and the list of
|
||||
* denominations in this group as a json-blob in the multihashmap
|
||||
* denominations_by_group.
|
||||
**/
|
||||
|
||||
{
|
||||
static const char *denoms_key = "denoms";
|
||||
struct groupData *group;
|
||||
json_t *list;
|
||||
json_t *entry;
|
||||
struct GNUNET_HashCode key;
|
||||
|
||||
/* Find the group/JSON-blob for the key */
|
||||
struct
|
||||
{
|
||||
enum TALER_DenominationCipher cipher;
|
||||
struct TALER_AgeMask age_mask;
|
||||
struct TALER_Amount value;
|
||||
struct TALER_DenomFeeSet fees;
|
||||
} meta = {
|
||||
.cipher = dk->denom_pub.cipher,
|
||||
.value = dk->meta.value,
|
||||
.fees = dk->meta.fees,
|
||||
.age_mask = dk->meta.age_mask,
|
||||
};
|
||||
|
||||
GNUNET_CRYPTO_hash (&meta, sizeof(meta), &key);
|
||||
|
||||
group = (struct groupData *) GNUNET_CONTAINER_multihashmap_get (
|
||||
denominations_by_group,
|
||||
&key);
|
||||
|
||||
if (NULL == group)
|
||||
{
|
||||
/*
|
||||
* There is no group for this meta-data yet, so let's create a new
|
||||
* group entry.
|
||||
*/
|
||||
|
||||
bool age_restricted = meta.age_mask.bits != 0;
|
||||
char *cipher;
|
||||
|
||||
group = GNUNET_new (struct groupData);
|
||||
group->hash_context = GNUNET_CRYPTO_hash_context_start ();
|
||||
|
||||
switch (meta.cipher)
|
||||
{
|
||||
case TALER_DENOMINATION_RSA:
|
||||
cipher = age_restricted ? "RSA+age_restriction": "RSA";
|
||||
break;
|
||||
case TALER_DENOMINATION_CS:
|
||||
cipher = age_restricted ? "CS+age_restriction": "CS";
|
||||
break;
|
||||
default:
|
||||
GNUNET_assert (false);
|
||||
}
|
||||
|
||||
group->json = GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_string ("cipher", cipher),
|
||||
TALER_JSON_PACK_DENOM_FEES ("fee", &meta.fees),
|
||||
TALER_JSON_pack_amount ("value", &meta.value));
|
||||
GNUNET_assert (NULL != group->json);
|
||||
|
||||
if (age_restricted)
|
||||
{
|
||||
GNUNET_assert (0 ==
|
||||
json_object_set (group->json,
|
||||
"age_mask",
|
||||
json_integer (meta.age_mask.bits)));
|
||||
}
|
||||
|
||||
/* Create a new array for the denominations in this group */
|
||||
list = json_array ();
|
||||
GNUNET_assert (NULL != list);
|
||||
GNUNET_assert (0 ==
|
||||
json_object_set (group->json, denoms_key, list));
|
||||
|
||||
GNUNET_assert (
|
||||
GNUNET_OK ==
|
||||
GNUNET_CONTAINER_multihashmap_put (denominations_by_group,
|
||||
&key,
|
||||
group,
|
||||
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
|
||||
}
|
||||
|
||||
/*
|
||||
* Now that we have found/created the right group, add the denomination
|
||||
* to the list
|
||||
*/
|
||||
{
|
||||
struct GNUNET_JSON_PackSpec key_spec;
|
||||
|
||||
switch (meta.cipher)
|
||||
{
|
||||
case TALER_DENOMINATION_RSA:
|
||||
key_spec =
|
||||
GNUNET_JSON_pack_rsa_public_key ("rsa_pub",
|
||||
dk->denom_pub.details.
|
||||
rsa_public_key);
|
||||
break;
|
||||
case TALER_DENOMINATION_CS:
|
||||
key_spec =
|
||||
GNUNET_JSON_pack_data_varsize ("cs_pub",
|
||||
&dk->denom_pub.details.
|
||||
cs_public_key,
|
||||
sizeof (dk->denom_pub.details.
|
||||
cs_public_key));
|
||||
break;
|
||||
default:
|
||||
GNUNET_assert (false);
|
||||
}
|
||||
|
||||
entry = GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_data_auto ("master_sig",
|
||||
&dk->master_sig),
|
||||
GNUNET_JSON_pack_timestamp ("stamp_start",
|
||||
dk->meta.start),
|
||||
GNUNET_JSON_pack_timestamp ("stamp_expire_withdraw",
|
||||
dk->meta.expire_withdraw),
|
||||
GNUNET_JSON_pack_timestamp ("stamp_expire_deposit",
|
||||
dk->meta.expire_deposit),
|
||||
GNUNET_JSON_pack_timestamp ("stamp_expire_legal",
|
||||
dk->meta.expire_legal),
|
||||
key_spec
|
||||
);
|
||||
GNUNET_assert (NULL != entry);
|
||||
}
|
||||
|
||||
/*
|
||||
* Build up the running hash of all denominations in this group
|
||||
* TODO: FIXME-oec: this is cipher and age_restriction dependend?!
|
||||
*/
|
||||
GNUNET_CRYPTO_hash_context_read (group->hash_context,
|
||||
&dk->h_denom_pub,
|
||||
sizeof (struct GNUNET_HashCode));
|
||||
|
||||
/* Finally, add the denomination to the list of denominations in this
|
||||
* group */
|
||||
list = json_object_get (group->json, denoms_key);
|
||||
GNUNET_assert (NULL != list);
|
||||
GNUNET_assert (true == json_is_array (list));
|
||||
GNUNET_assert (0 ==
|
||||
json_array_append_new (list, entry));
|
||||
}
|
||||
}
|
||||
|
||||
/* Create the JSON-array of grouped denominations */
|
||||
if (0 <
|
||||
GNUNET_CONTAINER_multihashmap_size (denominations_by_group))
|
||||
{
|
||||
struct GNUNET_CONTAINER_MultiHashMapIterator *iter;
|
||||
struct GNUNET_HashCode all_hashcode;
|
||||
struct GNUNET_HashContext *all_hash_ctx;
|
||||
struct groupData *group = NULL;
|
||||
|
||||
all_hash_ctx =
|
||||
GNUNET_CRYPTO_hash_context_start ();
|
||||
|
||||
iter =
|
||||
GNUNET_CONTAINER_multihashmap_iterator_create (denominations_by_group);
|
||||
|
||||
while (GNUNET_OK ==
|
||||
GNUNET_CONTAINER_multihashmap_iterator_next (iter, NULL, (const
|
||||
void **)
|
||||
&group))
|
||||
{
|
||||
struct GNUNET_HashCode hc;
|
||||
|
||||
GNUNET_CRYPTO_hash_context_finish (
|
||||
group->hash_context,
|
||||
&hc);
|
||||
|
||||
GNUNET_CRYPTO_hash_context_read (all_hash_ctx,
|
||||
&hc,
|
||||
sizeof (struct GNUNET_HashCode));
|
||||
|
||||
GNUNET_assert (0 ==
|
||||
json_object_set (
|
||||
group->json,
|
||||
"hash",
|
||||
GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_data_auto (NULL, &hc))));
|
||||
|
||||
GNUNET_assert (0 ==
|
||||
json_array_append_new (
|
||||
grouped_denominations,
|
||||
group->json));
|
||||
|
||||
GNUNET_free (group);
|
||||
}
|
||||
|
||||
GNUNET_CONTAINER_multihashmap_iterator_destroy (iter);
|
||||
GNUNET_CONTAINER_multihashmap_destroy (denominations_by_group);
|
||||
|
||||
GNUNET_CRYPTO_hash_context_finish (
|
||||
all_hash_ctx,
|
||||
&all_hashcode);
|
||||
|
||||
/* FIXME-oec: TODO:
|
||||
* sign all_hashcode and add the signature to the /keys response */
|
||||
}
|
||||
}
|
||||
|
||||
@ -2165,18 +2339,6 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
|
||||
{
|
||||
struct GNUNET_HashCode hc;
|
||||
|
||||
/* If age restriction is active and we had at least one denomination of
|
||||
* that sort, we simply add the hash of all age restricted denominations at
|
||||
* the end of the others. */
|
||||
if (0 && have_age_restricted_denoms)
|
||||
{
|
||||
struct GNUNET_HashCode hcr;
|
||||
GNUNET_CRYPTO_hash_context_finish (hash_context_restricted, &hcr);
|
||||
GNUNET_CRYPTO_hash_context_read (hash_context,
|
||||
&hcr,
|
||||
sizeof (struct GNUNET_HashCode));
|
||||
}
|
||||
|
||||
GNUNET_CRYPTO_hash_context_finish (hash_context,
|
||||
&hc);
|
||||
|
||||
@ -2187,14 +2349,12 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
|
||||
sctx.signkeys,
|
||||
recoup,
|
||||
denoms,
|
||||
age_restricted_denoms))
|
||||
grouped_denominations))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||
"Failed to generate key response data for %s\n",
|
||||
GNUNET_TIME_timestamp2s (last_cpd));
|
||||
json_decref (denoms);
|
||||
if (0 && NULL != age_restricted_denoms)
|
||||
json_decref (age_restricted_denoms);
|
||||
json_decref (sctx.signkeys);
|
||||
json_decref (recoup);
|
||||
return GNUNET_SYSERR;
|
||||
@ -2210,8 +2370,6 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
|
||||
json_decref (sctx.signkeys);
|
||||
json_decref (recoup);
|
||||
json_decref (denoms);
|
||||
if (NULL != age_restricted_denoms)
|
||||
json_decref (age_restricted_denoms);
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
@ -2387,11 +2545,13 @@ build_key_state (struct HelperState *hs,
|
||||
true);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (management_only)
|
||||
{
|
||||
ksh->management_only = true;
|
||||
return ksh;
|
||||
}
|
||||
|
||||
if (GNUNET_OK !=
|
||||
finish_keys_response (ksh))
|
||||
{
|
||||
@ -2401,6 +2561,7 @@ build_key_state (struct HelperState *hs,
|
||||
true);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ksh;
|
||||
}
|
||||
|
||||
|
@ -904,6 +904,14 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
" FROM exchange_do_purse_deposit"
|
||||
" ($1,$2,$3,$4,$5,$6,$7,$8);",
|
||||
8),
|
||||
/* Used in #postgres_update_aggregation_transient() */
|
||||
GNUNET_PQ_make_prepare (
|
||||
"set_purse_balance",
|
||||
"UPDATE purse_requests"
|
||||
" SET balance_val=$2"
|
||||
" ,balance_frac=$3"
|
||||
" WHERE purse_pub=$1;",
|
||||
3),
|
||||
/* used in #postgres_expire_purse() */
|
||||
GNUNET_PQ_make_prepare (
|
||||
"call_expire_purse",
|
||||
@ -1503,19 +1511,27 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
GNUNET_PQ_make_prepare (
|
||||
"audit_get_purse_deposits_incr",
|
||||
"SELECT"
|
||||
" amount_with_fee_val"
|
||||
",amount_with_fee_frac"
|
||||
",purse_pub"
|
||||
",coin_sig"
|
||||
" pd.amount_with_fee_val"
|
||||
",pd.amount_with_fee_frac"
|
||||
",pr.amount_with_fee_val AS total_val"
|
||||
",pr.amount_with_fee_frac AS total_frac"
|
||||
",pr.balance_val"
|
||||
",pr.balance_frac"
|
||||
",pr.flags"
|
||||
",pd.purse_pub"
|
||||
",pd.coin_sig"
|
||||
",partner_base_url"
|
||||
",denom.denom_pub"
|
||||
",pm.reserve_pub"
|
||||
",kc.coin_pub"
|
||||
",kc.age_commitment_hash"
|
||||
",purse_deposit_serial_id"
|
||||
" FROM purse_deposits"
|
||||
",pd.purse_deposit_serial_id"
|
||||
" FROM purse_deposits pd"
|
||||
" LEFT JOIN partners USING (partner_serial_id)"
|
||||
" JOIN known_coins kc USING (coin_pub)"
|
||||
" JOIN denominations denom USING (denominations_serial)"
|
||||
" LEFT JOIN purse_merges pm USING (purse_pub)"
|
||||
" JOIN purse_requests pr USING (purse_pub)"
|
||||
" JOIN known_coins kc USING (coin_pub)"
|
||||
" JOIN denominations denom USING (denominations_serial)"
|
||||
" WHERE ("
|
||||
" (purse_deposit_serial_id>=$1)"
|
||||
" )"
|
||||
@ -1523,7 +1539,7 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
1),
|
||||
|
||||
GNUNET_PQ_make_prepare (
|
||||
"audit_get_account_merges_incr",
|
||||
"audit_get_account_merge_incr",
|
||||
"SELECT"
|
||||
" am.account_merge_request_serial_id"
|
||||
",am.reserve_pub"
|
||||
@ -1548,12 +1564,14 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
1),
|
||||
|
||||
GNUNET_PQ_make_prepare (
|
||||
"audit_get_purse_merges_incr",
|
||||
"audit_get_purse_merge_incr",
|
||||
"SELECT"
|
||||
" pm.purse_merge_request_serial_id"
|
||||
",partner_base_url"
|
||||
",pr.amount_with_fee_val"
|
||||
",pr.amount_with_fee_frac"
|
||||
",pr.balance_val"
|
||||
",pr.balance_frac"
|
||||
",pr.flags"
|
||||
",pr.merge_pub"
|
||||
",pm.reserve_pub"
|
||||
@ -10532,21 +10550,36 @@ purse_deposit_serial_helper_cb (void *cls,
|
||||
};
|
||||
struct TALER_DenominationPublicKey denom_pub;
|
||||
uint64_t rowid;
|
||||
uint32_t flags32;
|
||||
struct TALER_ReservePublicKeyP reserve_pub;
|
||||
bool not_merged = false;
|
||||
struct TALER_Amount purse_balance;
|
||||
struct TALER_Amount purse_total;
|
||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||
TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
|
||||
&deposit.amount),
|
||||
TALER_PQ_RESULT_SPEC_AMOUNT ("balance",
|
||||
&purse_balance),
|
||||
TALER_PQ_RESULT_SPEC_AMOUNT ("total",
|
||||
&purse_total),
|
||||
TALER_PQ_RESULT_SPEC_AMOUNT ("deposit_fee",
|
||||
&deposit.deposit_fee),
|
||||
GNUNET_PQ_result_spec_allow_null (
|
||||
GNUNET_PQ_result_spec_string ("partner_base_url",
|
||||
&deposit.exchange_base_url),
|
||||
NULL),
|
||||
GNUNET_PQ_result_spec_allow_null (
|
||||
GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
|
||||
&reserve_pub),
|
||||
¬_merged),
|
||||
TALER_PQ_result_spec_denom_pub ("denom_pub",
|
||||
&denom_pub),
|
||||
GNUNET_PQ_result_spec_auto_from_type ("purse_pub",
|
||||
&deposit.purse_pub),
|
||||
GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
|
||||
&deposit.coin_sig),
|
||||
GNUNET_PQ_result_spec_uint32 ("flags",
|
||||
&flags32),
|
||||
GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
|
||||
&deposit.coin_pub),
|
||||
GNUNET_PQ_result_spec_allow_null (
|
||||
@ -10574,6 +10607,10 @@ purse_deposit_serial_helper_cb (void *cls,
|
||||
ret = dsc->cb (dsc->cb_cls,
|
||||
rowid,
|
||||
&deposit,
|
||||
not_merged ? NULL : &reserve_pub,
|
||||
(enum TALER_WalletAccountMergeFlags) flags32,
|
||||
&purse_balance,
|
||||
&purse_total,
|
||||
&denom_pub);
|
||||
GNUNET_PQ_cleanup_result (rs);
|
||||
if (GNUNET_OK != ret)
|
||||
@ -10623,6 +10660,120 @@ postgres_select_purse_deposits_above_serial_id (
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Closure for #account_merge_serial_helper_cb().
|
||||
*/
|
||||
struct AccountMergeSerialContext
|
||||
{
|
||||
|
||||
/**
|
||||
* Callback to call.
|
||||
*/
|
||||
TALER_EXCHANGEDB_AccountMergeCallback cb;
|
||||
|
||||
/**
|
||||
* Closure for @e cb.
|
||||
*/
|
||||
void *cb_cls;
|
||||
|
||||
/**
|
||||
* Plugin context.
|
||||
*/
|
||||
struct PostgresClosure *pg;
|
||||
|
||||
/**
|
||||
* Status code, set to #GNUNET_SYSERR on hard errors.
|
||||
*/
|
||||
enum GNUNET_GenericReturnValue status;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Helper function to be called with the results of a SELECT statement
|
||||
* that has returned @a num_results results.
|
||||
*
|
||||
* @param cls closure of type `struct AccountMergeSerialContext`
|
||||
* @param result the postgres result
|
||||
* @param num_results the number of results in @a result
|
||||
*/
|
||||
static void
|
||||
account_merge_serial_helper_cb (void *cls,
|
||||
PGresult *result,
|
||||
unsigned int num_results)
|
||||
{
|
||||
struct AccountMergeSerialContext *dsc = cls;
|
||||
struct PostgresClosure *pg = dsc->pg;
|
||||
|
||||
for (unsigned int i = 0; i<num_results; i++)
|
||||
{
|
||||
struct TALER_ReservePublicKeyP reserve_pub;
|
||||
struct TALER_PurseContractPublicKeyP purse_pub;
|
||||
struct TALER_PrivateContractHashP h_contract_terms;
|
||||
struct GNUNET_TIME_Timestamp purse_expiration;
|
||||
struct TALER_Amount amount;
|
||||
uint32_t min_age;
|
||||
uint32_t flags32;
|
||||
enum TALER_WalletAccountMergeFlags flags;
|
||||
struct TALER_Amount purse_fee;
|
||||
struct GNUNET_TIME_Timestamp merge_timestamp;
|
||||
struct TALER_ReserveSignatureP reserve_sig;
|
||||
uint64_t rowid;
|
||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||
TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
|
||||
&amount),
|
||||
TALER_PQ_RESULT_SPEC_AMOUNT ("purse_fee",
|
||||
&purse_fee),
|
||||
GNUNET_PQ_result_spec_uint32 ("flags",
|
||||
&flags32),
|
||||
GNUNET_PQ_result_spec_uint32 ("age_limit",
|
||||
&min_age),
|
||||
GNUNET_PQ_result_spec_timestamp ("purse_expiration",
|
||||
&purse_expiration),
|
||||
GNUNET_PQ_result_spec_timestamp ("merge_timestamp",
|
||||
&merge_timestamp),
|
||||
GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
|
||||
&h_contract_terms),
|
||||
GNUNET_PQ_result_spec_auto_from_type ("purse_pub",
|
||||
&purse_pub),
|
||||
GNUNET_PQ_result_spec_auto_from_type ("reserve_sig",
|
||||
&reserve_sig),
|
||||
GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
|
||||
&reserve_pub),
|
||||
GNUNET_PQ_result_spec_uint64 ("account_merge_request_serial_id",
|
||||
&rowid),
|
||||
GNUNET_PQ_result_spec_end
|
||||
};
|
||||
enum GNUNET_GenericReturnValue ret;
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_PQ_extract_result (result,
|
||||
rs,
|
||||
i))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
dsc->status = GNUNET_SYSERR;
|
||||
return;
|
||||
}
|
||||
flags = (enum TALER_WalletAccountMergeFlags) flags32;
|
||||
ret = dsc->cb (dsc->cb_cls,
|
||||
rowid,
|
||||
&reserve_pub,
|
||||
&purse_pub,
|
||||
&h_contract_terms,
|
||||
purse_expiration,
|
||||
&amount,
|
||||
min_age,
|
||||
flags,
|
||||
&purse_fee,
|
||||
merge_timestamp,
|
||||
&reserve_sig);
|
||||
GNUNET_PQ_cleanup_result (rs);
|
||||
if (GNUNET_OK != ret)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Select account merges above @a serial_id in monotonically increasing
|
||||
* order.
|
||||
@ -10640,8 +10791,139 @@ postgres_select_account_merges_above_serial_id (
|
||||
TALER_EXCHANGEDB_AccountMergeCallback cb,
|
||||
void *cb_cls)
|
||||
{
|
||||
GNUNET_break (0); // FIXME: not implemented
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
struct PostgresClosure *pg = cls;
|
||||
struct GNUNET_PQ_QueryParam params[] = {
|
||||
GNUNET_PQ_query_param_uint64 (&serial_id),
|
||||
GNUNET_PQ_query_param_end
|
||||
};
|
||||
struct AccountMergeSerialContext dsc = {
|
||||
.cb = cb,
|
||||
.cb_cls = cb_cls,
|
||||
.pg = pg,
|
||||
.status = GNUNET_OK
|
||||
};
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
|
||||
qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
|
||||
"audit_get_account_merge_incr",
|
||||
params,
|
||||
&account_merge_serial_helper_cb,
|
||||
&dsc);
|
||||
if (GNUNET_OK != dsc.status)
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
return qs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Closure for #purse_deposit_serial_helper_cb().
|
||||
*/
|
||||
struct PurseMergeSerialContext
|
||||
{
|
||||
|
||||
/**
|
||||
* Callback to call.
|
||||
*/
|
||||
TALER_EXCHANGEDB_PurseMergeCallback cb;
|
||||
|
||||
/**
|
||||
* Closure for @e cb.
|
||||
*/
|
||||
void *cb_cls;
|
||||
|
||||
/**
|
||||
* Plugin context.
|
||||
*/
|
||||
struct PostgresClosure *pg;
|
||||
|
||||
/**
|
||||
* Status code, set to #GNUNET_SYSERR on hard errors.
|
||||
*/
|
||||
enum GNUNET_GenericReturnValue status;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Helper function to be called with the results of a SELECT statement
|
||||
* that has returned @a num_results results.
|
||||
*
|
||||
* @param cls closure of type `struct PurseMergeSerialContext`
|
||||
* @param result the postgres result
|
||||
* @param num_results the number of results in @a result
|
||||
*/
|
||||
static void
|
||||
purse_merges_serial_helper_cb (void *cls,
|
||||
PGresult *result,
|
||||
unsigned int num_results)
|
||||
{
|
||||
struct PurseMergeSerialContext *dsc = cls;
|
||||
struct PostgresClosure *pg = dsc->pg;
|
||||
|
||||
for (unsigned int i = 0; i<num_results; i++)
|
||||
{
|
||||
uint64_t rowid;
|
||||
char *partner_base_url = NULL;
|
||||
struct TALER_Amount amount;
|
||||
struct TALER_Amount balance;
|
||||
uint32_t flags32;
|
||||
enum TALER_WalletAccountMergeFlags flags;
|
||||
struct TALER_PurseMergePublicKeyP merge_pub;
|
||||
struct TALER_ReservePublicKeyP reserve_pub;
|
||||
struct TALER_PurseMergeSignatureP merge_sig;
|
||||
struct TALER_PurseContractPublicKeyP purse_pub;
|
||||
struct GNUNET_TIME_Timestamp merge_timestamp;
|
||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||
TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
|
||||
&amount),
|
||||
TALER_PQ_RESULT_SPEC_AMOUNT ("balance",
|
||||
&balance),
|
||||
GNUNET_PQ_result_spec_allow_null (
|
||||
GNUNET_PQ_result_spec_string ("partner_base_url",
|
||||
&partner_base_url),
|
||||
NULL),
|
||||
GNUNET_PQ_result_spec_uint32 ("flags",
|
||||
&flags32),
|
||||
GNUNET_PQ_result_spec_timestamp ("merge_timestamp",
|
||||
&merge_timestamp),
|
||||
GNUNET_PQ_result_spec_auto_from_type ("purse_pub",
|
||||
&purse_pub),
|
||||
GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
|
||||
&reserve_pub),
|
||||
GNUNET_PQ_result_spec_auto_from_type ("merge_sig",
|
||||
&merge_sig),
|
||||
GNUNET_PQ_result_spec_auto_from_type ("merge_pub",
|
||||
&merge_pub),
|
||||
GNUNET_PQ_result_spec_uint64 ("purse_merge_request_serial_id",
|
||||
&rowid),
|
||||
GNUNET_PQ_result_spec_end
|
||||
};
|
||||
enum GNUNET_GenericReturnValue ret;
|
||||
|
||||
flags = (enum TALER_WalletAccountMergeFlags) flags;
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_PQ_extract_result (result,
|
||||
rs,
|
||||
i))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
dsc->status = GNUNET_SYSERR;
|
||||
return;
|
||||
}
|
||||
ret = dsc->cb (dsc->cb_cls,
|
||||
rowid,
|
||||
partner_base_url,
|
||||
&amount,
|
||||
&balance,
|
||||
flags,
|
||||
&merge_pub,
|
||||
&reserve_pub,
|
||||
&merge_sig,
|
||||
&purse_pub,
|
||||
merge_timestamp);
|
||||
GNUNET_PQ_cleanup_result (rs);
|
||||
if (GNUNET_OK != ret)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -10662,8 +10944,115 @@ postgres_select_purse_merges_above_serial_id (
|
||||
TALER_EXCHANGEDB_PurseMergeCallback cb,
|
||||
void *cb_cls)
|
||||
{
|
||||
GNUNET_break (0); // FIXME: not implemented
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
struct PostgresClosure *pg = cls;
|
||||
struct GNUNET_PQ_QueryParam params[] = {
|
||||
GNUNET_PQ_query_param_uint64 (&serial_id),
|
||||
GNUNET_PQ_query_param_end
|
||||
};
|
||||
struct PurseMergeSerialContext dsc = {
|
||||
.cb = cb,
|
||||
.cb_cls = cb_cls,
|
||||
.pg = pg,
|
||||
.status = GNUNET_OK
|
||||
};
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
|
||||
qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
|
||||
"audit_get_purse_merge_incr",
|
||||
params,
|
||||
&purse_merges_serial_helper_cb,
|
||||
&dsc);
|
||||
if (GNUNET_OK != dsc.status)
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
return qs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Closure for #purse_deposit_serial_helper_cb().
|
||||
*/
|
||||
struct HistoryRequestSerialContext
|
||||
{
|
||||
|
||||
/**
|
||||
* Callback to call.
|
||||
*/
|
||||
TALER_EXCHANGEDB_HistoryRequestCallback cb;
|
||||
|
||||
/**
|
||||
* Closure for @e cb.
|
||||
*/
|
||||
void *cb_cls;
|
||||
|
||||
/**
|
||||
* Plugin context.
|
||||
*/
|
||||
struct PostgresClosure *pg;
|
||||
|
||||
/**
|
||||
* Status code, set to #GNUNET_SYSERR on hard errors.
|
||||
*/
|
||||
enum GNUNET_GenericReturnValue status;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Helper function to be called with the results of a SELECT statement
|
||||
* that has returned @a num_results results.
|
||||
*
|
||||
* @param cls closure of type `struct HistoryRequestSerialContext`
|
||||
* @param result the postgres result
|
||||
* @param num_results the number of results in @a result
|
||||
*/
|
||||
static void
|
||||
history_request_serial_helper_cb (void *cls,
|
||||
PGresult *result,
|
||||
unsigned int num_results)
|
||||
{
|
||||
struct HistoryRequestSerialContext *dsc = cls;
|
||||
struct PostgresClosure *pg = dsc->pg;
|
||||
|
||||
for (unsigned int i = 0; i<num_results; i++)
|
||||
{
|
||||
uint64_t rowid;
|
||||
struct TALER_Amount history_fee;
|
||||
struct GNUNET_TIME_Timestamp ts;
|
||||
struct TALER_ReservePublicKeyP reserve_pub;
|
||||
struct TALER_ReserveSignatureP reserve_sig;
|
||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||
TALER_PQ_RESULT_SPEC_AMOUNT ("history_fee",
|
||||
&history_fee),
|
||||
GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
|
||||
&reserve_pub),
|
||||
GNUNET_PQ_result_spec_auto_from_type ("reserve_sig",
|
||||
&reserve_sig),
|
||||
GNUNET_PQ_result_spec_uint64 ("history_request_serial_id",
|
||||
&rowid),
|
||||
GNUNET_PQ_result_spec_timestamp ("request_timestamp",
|
||||
&ts),
|
||||
GNUNET_PQ_result_spec_end
|
||||
};
|
||||
enum GNUNET_GenericReturnValue ret;
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_PQ_extract_result (result,
|
||||
rs,
|
||||
i))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
dsc->status = GNUNET_SYSERR;
|
||||
return;
|
||||
}
|
||||
ret = dsc->cb (dsc->cb_cls,
|
||||
rowid,
|
||||
&history_fee,
|
||||
ts,
|
||||
&reserve_pub,
|
||||
&reserve_sig);
|
||||
GNUNET_PQ_cleanup_result (rs);
|
||||
if (GNUNET_OK != ret)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -10684,8 +11073,27 @@ postgres_select_history_requests_above_serial_id (
|
||||
TALER_EXCHANGEDB_HistoryRequestCallback cb,
|
||||
void *cb_cls)
|
||||
{
|
||||
GNUNET_break (0); // FIXME: not implemented
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
struct PostgresClosure *pg = cls;
|
||||
struct GNUNET_PQ_QueryParam params[] = {
|
||||
GNUNET_PQ_query_param_uint64 (&serial_id),
|
||||
GNUNET_PQ_query_param_end
|
||||
};
|
||||
struct HistoryRequestSerialContext dsc = {
|
||||
.cb = cb,
|
||||
.cb_cls = cb_cls,
|
||||
.pg = pg,
|
||||
.status = GNUNET_OK
|
||||
};
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
|
||||
qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
|
||||
"audit_get_history_requests_incr",
|
||||
params,
|
||||
&history_request_serial_helper_cb,
|
||||
&dsc);
|
||||
if (GNUNET_OK != dsc.status)
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
return qs;
|
||||
}
|
||||
|
||||
|
||||
@ -15173,6 +15581,35 @@ postgres_do_purse_deposit (
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the current @a balance in the purse
|
||||
* identified by @a purse_pub. Used by the auditor
|
||||
* to update the balance as calculated by the auditor.
|
||||
*
|
||||
* @param cls closure
|
||||
* @param purse_pub public key of a purse
|
||||
* @param balance new balance to store under the purse
|
||||
* @return transaction status
|
||||
*/
|
||||
static enum GNUNET_DB_QueryStatus
|
||||
postgres_set_purse_balance (
|
||||
void *cls,
|
||||
const struct TALER_PurseContractPublicKeyP *purse_pub,
|
||||
const struct TALER_Amount *balance)
|
||||
{
|
||||
struct PostgresClosure *pg = cls;
|
||||
struct GNUNET_PQ_QueryParam params[] = {
|
||||
GNUNET_PQ_query_param_auto_from_type (purse_pub),
|
||||
TALER_PQ_query_param_amount (balance),
|
||||
GNUNET_PQ_query_param_end
|
||||
};
|
||||
|
||||
return GNUNET_PQ_eval_prepared_non_select (pg->conn,
|
||||
"set_purse_balance",
|
||||
params);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function called to obtain a coin deposit data from
|
||||
* depositing the coin into a purse.
|
||||
@ -15804,6 +16241,8 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
|
||||
= &postgres_select_purse_by_merge_pub;
|
||||
plugin->do_purse_deposit
|
||||
= &postgres_do_purse_deposit;
|
||||
plugin->set_purse_balance
|
||||
= &postgres_set_purse_balance;
|
||||
plugin->get_purse_deposit
|
||||
= &postgres_get_purse_deposit;
|
||||
plugin->do_purse_merge
|
||||
|
@ -1990,6 +1990,11 @@ typedef enum GNUNET_GenericReturnValue
|
||||
* @param cls closure
|
||||
* @param rowid unique serial ID for the deposit in our DB
|
||||
* @param deposit deposit details
|
||||
* @param reserve_pub which reserve is the purse merged into, NULL if unknown
|
||||
* @param flags purse flags
|
||||
* @param auditor_balance purse balance (according to the
|
||||
* auditor during auditing)
|
||||
* @param purse_total target amount the purse should reach
|
||||
* @param denom_pub denomination public key of @a coin_pub
|
||||
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
|
||||
*/
|
||||
@ -1998,6 +2003,10 @@ typedef enum GNUNET_GenericReturnValue
|
||||
void *cls,
|
||||
uint64_t rowid,
|
||||
const struct TALER_EXCHANGEDB_PurseDeposit *deposit,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
enum TALER_WalletAccountMergeFlags flags,
|
||||
const struct TALER_Amount *auditor_balance,
|
||||
const struct TALER_Amount *purse_total,
|
||||
const struct TALER_DenominationPublicKey *denom_pub);
|
||||
|
||||
|
||||
@ -2023,7 +2032,7 @@ typedef enum GNUNET_GenericReturnValue
|
||||
enum TALER_WalletAccountMergeFlags flags,
|
||||
const struct TALER_Amount *purse_fee,
|
||||
struct GNUNET_TIME_Timestamp merge_timestamp,
|
||||
struct TALER_ReserveSignatureP *reserve_sig);
|
||||
const struct TALER_ReserveSignatureP *reserve_sig);
|
||||
|
||||
|
||||
/**
|
||||
@ -2033,6 +2042,15 @@ typedef enum GNUNET_GenericReturnValue
|
||||
*
|
||||
* @param cls closure
|
||||
* @param rowid unique serial ID for the deposit in our DB
|
||||
* @param partner_base_url where is the reserve, NULL for this exchange
|
||||
* @param amount total amount expected in the purse
|
||||
* @param balance current balance in the purse (according to the auditor)
|
||||
* @param flags purse flags
|
||||
* @param merge_pub merge capability key
|
||||
* @param reserve_pub reserve the merge affects
|
||||
* @param merge_sig signature affirming the merge
|
||||
* @param purse_pub purse key
|
||||
* @param merge_timestamp when did the merge happen
|
||||
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
|
||||
*/
|
||||
typedef enum GNUNET_GenericReturnValue
|
||||
@ -2041,6 +2059,7 @@ typedef enum GNUNET_GenericReturnValue
|
||||
uint64_t rowid,
|
||||
const char *partner_base_url,
|
||||
const struct TALER_Amount *amount,
|
||||
const struct TALER_Amount *balance,
|
||||
enum TALER_WalletAccountMergeFlags flags,
|
||||
const struct TALER_PurseMergePublicKeyP *merge_pub,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
@ -5290,6 +5309,23 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
bool *conflict);
|
||||
|
||||
|
||||
/**
|
||||
* Set the current @a balance in the purse
|
||||
* identified by @a purse_pub. Used by the auditor
|
||||
* to update the balance as calculated by the auditor.
|
||||
*
|
||||
* @param cls closure
|
||||
* @param purse_pub public key of a purse
|
||||
* @param balance new balance to store under the purse
|
||||
* @return transaction status
|
||||
*/
|
||||
enum GNUNET_DB_QueryStatus
|
||||
(*set_purse_balance)(
|
||||
void *cls,
|
||||
const struct TALER_PurseContractPublicKeyP *purse_pub,
|
||||
const struct TALER_Amount *balance);
|
||||
|
||||
|
||||
/**
|
||||
* Function called to obtain a coin deposit data from
|
||||
* depositing the coin into a purse.
|
||||
|
@ -417,6 +417,19 @@ char *
|
||||
TALER_payto_validate (const char *payto_uri);
|
||||
|
||||
|
||||
/**
|
||||
* Create payto://-URI for a given exchange base URL
|
||||
* and a @a reserve_pub.
|
||||
*
|
||||
* @param exchange_url the base URL of the exchange
|
||||
* @param reserve_pub the public key of the reserve
|
||||
* @return payto://-URI for the reserve (without receiver-name!)
|
||||
*/
|
||||
char *
|
||||
TALER_reserve_make_payto (const char *exchange_url,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub);
|
||||
|
||||
|
||||
/**
|
||||
* Check that an IBAN number is well-formed.
|
||||
*
|
||||
|
@ -119,50 +119,6 @@ struct TALER_EXCHANGE_AccountMergeHandle
|
||||
};
|
||||
|
||||
|
||||
static char *
|
||||
make_payto (const char *exchange_url,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub)
|
||||
{
|
||||
char pub_str[sizeof (*reserve_pub) * 2];
|
||||
char *end;
|
||||
bool is_http;
|
||||
char *reserve_url;
|
||||
|
||||
end = GNUNET_STRINGS_data_to_string (
|
||||
reserve_pub,
|
||||
sizeof (*reserve_pub),
|
||||
pub_str,
|
||||
sizeof (pub_str));
|
||||
*end = '\0';
|
||||
if (0 == strncmp (exchange_url,
|
||||
"http://",
|
||||
strlen ("http://")))
|
||||
{
|
||||
is_http = true;
|
||||
exchange_url = &exchange_url[strlen ("http://")];
|
||||
}
|
||||
else if (0 == strncmp (exchange_url,
|
||||
"https://",
|
||||
strlen ("https://")))
|
||||
{
|
||||
is_http = false;
|
||||
exchange_url = &exchange_url[strlen ("https://")];
|
||||
}
|
||||
else
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
/* exchange_url includes trailing '/' */
|
||||
GNUNET_asprintf (&reserve_url,
|
||||
"payto://%s/%s%s",
|
||||
is_http ? "taler+http" : "taler",
|
||||
exchange_url,
|
||||
pub_str);
|
||||
return reserve_url;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function called when we're done processing the
|
||||
* HTTP /purse/$PID/merge request.
|
||||
@ -379,8 +335,8 @@ TALER_EXCHANGE_account_merge (
|
||||
"/purses/%s/merge",
|
||||
pub_str);
|
||||
}
|
||||
reserve_url = make_payto (pch->provider_url,
|
||||
&pch->reserve_pub);
|
||||
reserve_url = TALER_reserve_make_payto (pch->provider_url,
|
||||
&pch->reserve_pub);
|
||||
if (NULL == reserve_url)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
|
@ -312,4 +312,48 @@ TALER_payto_from_reserve (const char *exchange_base_url,
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
TALER_reserve_make_payto (const char *exchange_url,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub)
|
||||
{
|
||||
char pub_str[sizeof (*reserve_pub) * 2];
|
||||
char *end;
|
||||
bool is_http;
|
||||
char *reserve_url;
|
||||
|
||||
end = GNUNET_STRINGS_data_to_string (
|
||||
reserve_pub,
|
||||
sizeof (*reserve_pub),
|
||||
pub_str,
|
||||
sizeof (pub_str));
|
||||
*end = '\0';
|
||||
if (0 == strncmp (exchange_url,
|
||||
"http://",
|
||||
strlen ("http://")))
|
||||
{
|
||||
is_http = true;
|
||||
exchange_url = &exchange_url[strlen ("http://")];
|
||||
}
|
||||
else if (0 == strncmp (exchange_url,
|
||||
"https://",
|
||||
strlen ("https://")))
|
||||
{
|
||||
is_http = false;
|
||||
exchange_url = &exchange_url[strlen ("https://")];
|
||||
}
|
||||
else
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
/* exchange_url includes trailing '/' */
|
||||
GNUNET_asprintf (&reserve_url,
|
||||
"payto://%s/%s%s",
|
||||
is_http ? "taler+http" : "taler",
|
||||
exchange_url,
|
||||
pub_str);
|
||||
return reserve_url;
|
||||
}
|
||||
|
||||
|
||||
/* end of payto.c */
|
||||
|
Loading…
Reference in New Issue
Block a user