aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/auditor/taler-helper-auditor-coins.c13
-rw-r--r--src/auditor/taler-helper-auditor-reserves.c195
-rw-r--r--src/exchangedb/plugin_exchangedb_postgres.c88
-rw-r--r--src/include/taler_exchangedb_plugin.h36
-rw-r--r--src/lib/exchange_api_purse_merge.c48
5 files changed, 304 insertions, 76 deletions
diff --git a/src/auditor/taler-helper-auditor-coins.c b/src/auditor/taler-helper-auditor-coins.c
index e33364844..8021b3982 100644
--- a/src/auditor/taler-helper-auditor-coins.c
+++ b/src/auditor/taler-helper-auditor-coins.c
@@ -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,
diff --git a/src/auditor/taler-helper-auditor-reserves.c b/src/auditor/taler-helper-auditor-reserves.c
index 49176dcfa..a3976bc9a 100644
--- a/src/auditor/taler-helper-auditor-reserves.c
+++ b/src/auditor/taler-helper-auditor-reserves.c
@@ -70,6 +70,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.
*/
static struct TALER_Amount total_balance_insufficient_loss;
@@ -754,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
@@ -1255,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
*/
@@ -1263,12 +1275,25 @@ 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)
{
+ 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,
@@ -1293,10 +1318,87 @@ handle_purse_deposits (
return GNUNET_OK;
}
- GNUNET_break (0); // FIXME
- // FIXME: need flags + total deposited!
- /* Credit purse value (if last op)! */
- return GNUNET_SYSERR;
+ {
+ 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;
}
@@ -1307,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
@@ -1315,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,
@@ -1326,6 +1438,9 @@ handle_purse_merged (
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
@@ -1376,10 +1491,34 @@ handle_purse_merged (
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: set to what?;
+ // 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;
}
@@ -1411,6 +1550,9 @@ handle_account_merged (
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,
@@ -1476,6 +1618,9 @@ handle_history_request (
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,
@@ -1616,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,
@@ -1648,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,
@@ -1823,6 +1968,9 @@ run (void *cls,
(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 ()));
GNUNET_assert (NULL !=
@@ -1842,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),
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index 523ccff48..5177ff55e 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -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)"
" )"
@@ -1554,6 +1570,8 @@ prepare_statements (struct PostgresClosure *pg)
",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),
+ &not_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)
@@ -10827,6 +10864,7 @@ purse_merges_serial_helper_cb (void *cls,
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;
@@ -10837,6 +10875,8 @@ purse_merges_serial_helper_cb (void *cls,
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),
@@ -10873,6 +10913,7 @@ purse_merges_serial_helper_cb (void *cls,
rowid,
partner_base_url,
&amount,
+ &balance,
flags,
&merge_pub,
&reserve_pub,
@@ -15541,6 +15582,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.
*
@@ -16171,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
diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h
index 5ef4e74ad..2c59d6785 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -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);
@@ -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,
@@ -5291,6 +5310,23 @@ struct TALER_EXCHANGEDB_Plugin
/**
+ * 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.
*
diff --git a/src/lib/exchange_api_purse_merge.c b/src/lib/exchange_api_purse_merge.c
index 6b6c37519..abe6d8cf9 100644
--- a/src/lib/exchange_api_purse_merge.c
+++ b/src/lib/exchange_api_purse_merge.c
@@ -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);