-towards coin audits with purse deposits
This commit is contained in:
parent
70a5ceecc1
commit
58a0882909
@ -1 +1 @@
|
|||||||
1655064974
|
1655124520
|
||||||
|
@ -113,7 +113,7 @@ currency = TESTKUDOS
|
|||||||
[merchant-exchange-default]
|
[merchant-exchange-default]
|
||||||
CURRENCY = TESTKUDOS
|
CURRENCY = TESTKUDOS
|
||||||
EXCHANGE_BASE_URL = http://localhost:8081/
|
EXCHANGE_BASE_URL = http://localhost:8081/
|
||||||
MASTER_KEY = QRZFN2H2C1FANGHV76FBN11ESTK72VFCG3BVSRZA6PHJNT9WG3SG
|
MASTER_KEY = GPB1CSPV6E49MET2PX6BFWVBGFF8BAE14M05RJB54C28EY1HX42G
|
||||||
|
|
||||||
[merchant-account-merchant]
|
[merchant-account-merchant]
|
||||||
ACTIVE_default = YES
|
ACTIVE_default = YES
|
||||||
@ -157,7 +157,7 @@ CONFIG = postgres:///auditor-basedb
|
|||||||
[exchange]
|
[exchange]
|
||||||
LOOKAHEAD_SIGN = 32 weeks 1 day
|
LOOKAHEAD_SIGN = 32 weeks 1 day
|
||||||
SIGNKEY_DURATION = 4 weeks
|
SIGNKEY_DURATION = 4 weeks
|
||||||
MASTER_PUBLIC_KEY = QRZFN2H2C1FANGHV76FBN11ESTK72VFCG3BVSRZA6PHJNT9WG3SG
|
MASTER_PUBLIC_KEY = GPB1CSPV6E49MET2PX6BFWVBGFF8BAE14M05RJB54C28EY1HX42G
|
||||||
SIGNKEY_LEGAL_DURATION = 4 weeks
|
SIGNKEY_LEGAL_DURATION = 4 weeks
|
||||||
UNIXPATH = ${TALER_RUNTIME_DIR}/exchange.http
|
UNIXPATH = ${TALER_RUNTIME_DIR}/exchange.http
|
||||||
|
|
||||||
@ -175,7 +175,7 @@ DATABASE = postgres:///auditor-basedb
|
|||||||
CONFIG = postgres:///auditor-basedb
|
CONFIG = postgres:///auditor-basedb
|
||||||
|
|
||||||
[auditor]
|
[auditor]
|
||||||
PUBLIC_KEY = X25D3Y3K4SJZHP3KPP48R3PM9ZSYCEVEZK1SBXAMCRTTGN6CV32G
|
PUBLIC_KEY = FBVV6V14GCCR95X2W2PMCBTFYZ4S3SX3JN504M8SJTMK1JBBV99G
|
||||||
TINY_AMOUNT = TESTKUDOS:0.01
|
TINY_AMOUNT = TESTKUDOS:0.01
|
||||||
BASE_URL = http://localhost:8083/
|
BASE_URL = http://localhost:8083/
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
QRZFN2H2C1FANGHV76FBN11ESTK72VFCG3BVSRZA6PHJNT9WG3SG
|
GPB1CSPV6E49MET2PX6BFWVBGFF8BAE14M05RJB54C28EY1HX42G
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -61,6 +61,11 @@ struct TALER_AuditorPublicKeyP TALER_ARL_auditor_pub;
|
|||||||
*/
|
*/
|
||||||
char *TALER_ARL_auditor_url;
|
char *TALER_ARL_auditor_url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API endpoint of the exchange.
|
||||||
|
*/
|
||||||
|
char *TALER_ARL_exchange_url;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* At what time did the auditor process start?
|
* At what time did the auditor process start?
|
||||||
*/
|
*/
|
||||||
@ -371,10 +376,13 @@ test_master_present (void *cls,
|
|||||||
{
|
{
|
||||||
int *found = cls;
|
int *found = cls;
|
||||||
|
|
||||||
(void) exchange_url;
|
|
||||||
if (0 == GNUNET_memcmp (mpub,
|
if (0 == GNUNET_memcmp (mpub,
|
||||||
&TALER_ARL_master_pub))
|
&TALER_ARL_master_pub))
|
||||||
|
{
|
||||||
*found = GNUNET_YES;
|
*found = GNUNET_YES;
|
||||||
|
GNUNET_free (TALER_ARL_exchange_url);
|
||||||
|
TALER_ARL_exchange_url = GNUNET_strdup (exchange_url);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -765,6 +773,7 @@ TALER_ARL_done (json_t *report)
|
|||||||
JSON_INDENT (2));
|
JSON_INDENT (2));
|
||||||
json_decref (report);
|
json_decref (report);
|
||||||
}
|
}
|
||||||
|
GNUNET_free (TALER_ARL_exchange_url);
|
||||||
GNUNET_free (TALER_ARL_auditor_url);
|
GNUNET_free (TALER_ARL_auditor_url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +74,11 @@ extern struct TALER_AuditorPublicKeyP TALER_ARL_auditor_pub;
|
|||||||
*/
|
*/
|
||||||
extern char *TALER_ARL_auditor_url;
|
extern char *TALER_ARL_auditor_url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API endpoint of the exchange.
|
||||||
|
*/
|
||||||
|
extern char *TALER_ARL_exchange_url;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* At what time did the auditor process start?
|
* At what time did the auditor process start?
|
||||||
*/
|
*/
|
||||||
|
@ -1 +1 @@
|
|||||||
1655066138
|
1655124599
|
||||||
|
@ -1 +1 @@
|
|||||||
RJD4G3ERAWDZRH8W4PMNKB9X75HB3N1A3MFKMHBH4FTAAD71GA90
|
6CF031C2JWXQB98SNHARWSPJMYR8JM26BVDV08CPH63T2M9JXV30
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -115,6 +115,7 @@ static struct Table tables[] = {
|
|||||||
{ .rt = TALER_EXCHANGEDB_RT_EXTENSIONS},
|
{ .rt = TALER_EXCHANGEDB_RT_EXTENSIONS},
|
||||||
{ .rt = TALER_EXCHANGEDB_RT_EXTENSION_DETAILS },
|
{ .rt = TALER_EXCHANGEDB_RT_EXTENSION_DETAILS },
|
||||||
{ .rt = TALER_EXCHANGEDB_RT_PURSE_REQUESTS},
|
{ .rt = TALER_EXCHANGEDB_RT_PURSE_REQUESTS},
|
||||||
|
{ .rt = TALER_EXCHANGEDB_RT_PURSE_REFUNDS},
|
||||||
{ .rt = TALER_EXCHANGEDB_RT_PURSE_MERGES},
|
{ .rt = TALER_EXCHANGEDB_RT_PURSE_MERGES},
|
||||||
{ .rt = TALER_EXCHANGEDB_RT_PURSE_DEPOSITS},
|
{ .rt = TALER_EXCHANGEDB_RT_PURSE_DEPOSITS},
|
||||||
{ .rt = TALER_EXCHANGEDB_RT_ACCOUNT_MERGES},
|
{ .rt = TALER_EXCHANGEDB_RT_ACCOUNT_MERGES},
|
||||||
|
@ -17,9 +17,6 @@
|
|||||||
* @file auditor/taler-helper-auditor-coins.c
|
* @file auditor/taler-helper-auditor-coins.c
|
||||||
* @brief audits coins in an exchange database.
|
* @brief audits coins in an exchange database.
|
||||||
* @author Christian Grothoff
|
* @author Christian Grothoff
|
||||||
*
|
|
||||||
* UNDECIDED:
|
|
||||||
* - do we care about checking the 'done' flag in deposit_cb?
|
|
||||||
*/
|
*/
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include <gnunet/gnunet_util_lib.h>
|
#include <gnunet/gnunet_util_lib.h>
|
||||||
@ -248,7 +245,8 @@ get_cached_history (const struct TALER_CoinSpendPublicKeyP *coin_pub)
|
|||||||
{
|
{
|
||||||
unsigned int i = coin_history_index (coin_pub);
|
unsigned int i = coin_history_index (coin_pub);
|
||||||
|
|
||||||
if (0 == GNUNET_memcmp (coin_pub,
|
if (0 ==
|
||||||
|
GNUNET_memcmp (coin_pub,
|
||||||
&coin_histories[i].coin_pub))
|
&coin_histories[i].coin_pub))
|
||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||||
@ -479,7 +477,6 @@ check_coin_history (const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
|||||||
&tl);
|
&tl);
|
||||||
if (0 >= qs)
|
if (0 >= qs)
|
||||||
return qs;
|
return qs;
|
||||||
|
|
||||||
GNUNET_assert (GNUNET_OK ==
|
GNUNET_assert (GNUNET_OK ==
|
||||||
TALER_amount_set_zero (value->currency,
|
TALER_amount_set_zero (value->currency,
|
||||||
&refunded));
|
&refunded));
|
||||||
@ -538,6 +535,7 @@ check_coin_history (const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
|||||||
&pos->details.recoup_refresh->value);
|
&pos->details.recoup_refresh->value);
|
||||||
break;
|
break;
|
||||||
case TALER_EXCHANGEDB_TT_PURSE_DEPOSIT:
|
case TALER_EXCHANGEDB_TT_PURSE_DEPOSIT:
|
||||||
|
/* spent += pos->value */
|
||||||
TALER_ARL_amount_add (&spent,
|
TALER_ARL_amount_add (&spent,
|
||||||
&spent,
|
&spent,
|
||||||
&pos->details.purse_deposit->amount);
|
&pos->details.purse_deposit->amount);
|
||||||
@ -628,22 +626,22 @@ struct DenominationSummary
|
|||||||
const struct TALER_EXCHANGEDB_DenominationKeyInformation *issue;
|
const struct TALER_EXCHANGEDB_DenominationKeyInformation *issue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* #GNUNET_YES if this record already existed in the DB.
|
* True if this record already existed in the DB.
|
||||||
* Used to decide between insert/update in
|
* Used to decide between insert/update in
|
||||||
* #sync_denomination().
|
* #sync_denomination().
|
||||||
*/
|
*/
|
||||||
int in_db;
|
bool in_db;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should we report an emergency for this denomination, causing it to be
|
* Should we report an emergency for this denomination, causing it to be
|
||||||
* revoked (because more coins were deposited than issued)?
|
* revoked (because more coins were deposited than issued)?
|
||||||
*/
|
*/
|
||||||
int report_emergency;
|
bool report_emergency;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* #GNUNET_YES if this denomination was revoked.
|
* True if this denomination was revoked.
|
||||||
*/
|
*/
|
||||||
int was_revoked;
|
bool was_revoked;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -695,7 +693,7 @@ init_denomination (const struct TALER_DenominationHashP *denom_hash,
|
|||||||
}
|
}
|
||||||
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
|
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
|
||||||
{
|
{
|
||||||
ds->in_db = GNUNET_YES;
|
ds->in_db = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -741,10 +739,10 @@ init_denomination (const struct TALER_DenominationHashP *denom_hash,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ds->was_revoked = GNUNET_YES;
|
ds->was_revoked = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (GNUNET_YES == ds->in_db)
|
return ds->in_db
|
||||||
? GNUNET_DB_STATUS_SUCCESS_ONE_RESULT
|
? GNUNET_DB_STATUS_SUCCESS_ONE_RESULT
|
||||||
: GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
|
: GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
|
||||||
}
|
}
|
||||||
@ -900,7 +898,7 @@ sync_denomination (void *cls,
|
|||||||
cnt,
|
cnt,
|
||||||
&ds->denom_risk);
|
&ds->denom_risk);
|
||||||
}
|
}
|
||||||
if (GNUNET_YES == ds->report_emergency)
|
if (ds->report_emergency)
|
||||||
{
|
{
|
||||||
/* Value of coins deposited exceed value of coins
|
/* Value of coins deposited exceed value of coins
|
||||||
issued! Also very bad! */
|
issued! Also very bad! */
|
||||||
@ -1139,9 +1137,9 @@ reveal_data_cb (void *cls,
|
|||||||
* #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT
|
* #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT
|
||||||
*/
|
*/
|
||||||
static enum GNUNET_DB_QueryStatus
|
static enum GNUNET_DB_QueryStatus
|
||||||
check_known_coin (const char *operation,
|
check_known_coin (
|
||||||
const struct
|
const char *operation,
|
||||||
TALER_EXCHANGEDB_DenominationKeyInformation *issue,
|
const struct TALER_EXCHANGEDB_DenominationKeyInformation *issue,
|
||||||
uint64_t rowid,
|
uint64_t rowid,
|
||||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||||
const struct TALER_DenominationPublicKey *denom_pub,
|
const struct TALER_DenominationPublicKey *denom_pub,
|
||||||
@ -1463,6 +1461,7 @@ refresh_session_cb (void *cls,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// FIXME: refactor: repeated logic!
|
||||||
if (TALER_ARL_SR_INVALID_NEGATIVE ==
|
if (TALER_ARL_SR_INVALID_NEGATIVE ==
|
||||||
TALER_ARL_amount_subtract_neg (&tmp,
|
TALER_ARL_amount_subtract_neg (&tmp,
|
||||||
&dso->denom_balance,
|
&dso->denom_balance,
|
||||||
@ -1471,7 +1470,7 @@ refresh_session_cb (void *cls,
|
|||||||
TALER_ARL_amount_add (&dso->denom_loss,
|
TALER_ARL_amount_add (&dso->denom_loss,
|
||||||
&dso->denom_loss,
|
&dso->denom_loss,
|
||||||
amount_with_fee);
|
amount_with_fee);
|
||||||
dso->report_emergency = GNUNET_YES;
|
dso->report_emergency = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1650,6 +1649,7 @@ deposit_cb (void *cls,
|
|||||||
{
|
{
|
||||||
struct TALER_Amount tmp;
|
struct TALER_Amount tmp;
|
||||||
|
|
||||||
|
// FIXME: refactor: repeated logic!
|
||||||
if (TALER_ARL_SR_INVALID_NEGATIVE ==
|
if (TALER_ARL_SR_INVALID_NEGATIVE ==
|
||||||
TALER_ARL_amount_subtract_neg (&tmp,
|
TALER_ARL_amount_subtract_neg (&tmp,
|
||||||
&ds->denom_balance,
|
&ds->denom_balance,
|
||||||
@ -1658,7 +1658,7 @@ deposit_cb (void *cls,
|
|||||||
TALER_ARL_amount_add (&ds->denom_loss,
|
TALER_ARL_amount_add (&ds->denom_loss,
|
||||||
&ds->denom_loss,
|
&ds->denom_loss,
|
||||||
&deposit->amount_with_fee);
|
&deposit->amount_with_fee);
|
||||||
ds->report_emergency = GNUNET_YES;
|
ds->report_emergency = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1718,6 +1718,7 @@ deposit_cb (void *cls,
|
|||||||
* @param merchant_sig signature of the merchant
|
* @param merchant_sig signature of the merchant
|
||||||
* @param h_contract_terms hash of the proposal data known to merchant and customer
|
* @param h_contract_terms hash of the proposal data known to merchant and customer
|
||||||
* @param rtransaction_id refund transaction ID chosen by the merchant
|
* @param rtransaction_id refund transaction ID chosen by the merchant
|
||||||
|
* @param full_refund true if the refunds total up to the entire deposited value
|
||||||
* @param amount_with_fee amount that was deposited including fee
|
* @param amount_with_fee amount that was deposited including fee
|
||||||
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
|
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
|
||||||
*/
|
*/
|
||||||
@ -1730,6 +1731,7 @@ refund_cb (void *cls,
|
|||||||
const struct TALER_MerchantSignatureP *merchant_sig,
|
const struct TALER_MerchantSignatureP *merchant_sig,
|
||||||
const struct TALER_PrivateContractHashP *h_contract_terms,
|
const struct TALER_PrivateContractHashP *h_contract_terms,
|
||||||
uint64_t rtransaction_id,
|
uint64_t rtransaction_id,
|
||||||
|
bool full_refund,
|
||||||
const struct TALER_Amount *amount_with_fee)
|
const struct TALER_Amount *amount_with_fee)
|
||||||
{
|
{
|
||||||
struct CoinContext *cc = cls;
|
struct CoinContext *cc = cls;
|
||||||
@ -1840,6 +1842,153 @@ refund_cb (void *cls,
|
|||||||
TALER_ARL_amount_add (&total_refund_fee_income,
|
TALER_ARL_amount_add (&total_refund_fee_income,
|
||||||
&total_refund_fee_income,
|
&total_refund_fee_income,
|
||||||
&issue->fees.refund);
|
&issue->fees.refund);
|
||||||
|
if (full_refund)
|
||||||
|
{
|
||||||
|
TALER_ARL_amount_subtract (&total_deposit_fee_income,
|
||||||
|
&total_deposit_fee_income,
|
||||||
|
&issue->fees.deposit);
|
||||||
|
}
|
||||||
|
if (TALER_ARL_do_abort ())
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called with details about purse refunds that have been made, with
|
||||||
|
* the goal of auditing the purse refund's execution.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param amount_with_fee amount of the deposit into the purse
|
||||||
|
* @param coin_pub coin that is to be refunded the @a given amount_with_fee
|
||||||
|
* @param denom_pub denomination of @a coin_pub
|
||||||
|
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
|
||||||
|
*/
|
||||||
|
static enum GNUNET_GenericReturnValue
|
||||||
|
purse_refund_coin_cb (
|
||||||
|
void *cls,
|
||||||
|
const struct TALER_Amount *amount_with_fee,
|
||||||
|
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||||
|
const struct TALER_DenominationPublicKey *denom_pub)
|
||||||
|
{
|
||||||
|
struct CoinContext *cc = cls;
|
||||||
|
|
||||||
|
#if FIXME
|
||||||
|
const struct TALER_EXCHANGEDB_DenominationKeyInformation *issue;
|
||||||
|
struct DenominationSummary *ds;
|
||||||
|
struct TALER_Amount amount_without_fee;
|
||||||
|
enum GNUNET_DB_QueryStatus qs;
|
||||||
|
|
||||||
|
qs = TALER_ARL_get_denomination_info (denom_pub,
|
||||||
|
&issue,
|
||||||
|
NULL);
|
||||||
|
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
|
||||||
|
{
|
||||||
|
report_row_inconsistency ("purse-refunds",
|
||||||
|
rowid,
|
||||||
|
"denomination key not found");
|
||||||
|
if (TALER_ARL_do_abort ())
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
|
||||||
|
{
|
||||||
|
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TALER_ARL_SR_INVALID_NEGATIVE ==
|
||||||
|
TALER_ARL_amount_subtract_neg (&amount_without_fee,
|
||||||
|
amount_with_fee,
|
||||||
|
&issue->fees.refund))
|
||||||
|
{
|
||||||
|
report_amount_arithmetic_inconsistency ("refund (fee)",
|
||||||
|
rowid,
|
||||||
|
&amount_without_fee,
|
||||||
|
&issue->fees.refund,
|
||||||
|
-1);
|
||||||
|
if (TALER_ARL_do_abort ())
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||||
|
"Refunding coin %s in denomination `%s' value %s\n",
|
||||||
|
TALER_B2S (coin_pub),
|
||||||
|
GNUNET_h2s (&issue->denom_hash.hash),
|
||||||
|
TALER_amount2s (amount_with_fee));
|
||||||
|
|
||||||
|
/* update coin's denomination balance */
|
||||||
|
ds = get_denomination_summary (cc,
|
||||||
|
issue,
|
||||||
|
&issue->denom_hash);
|
||||||
|
if (NULL == ds)
|
||||||
|
{
|
||||||
|
report_row_inconsistency ("refund",
|
||||||
|
rowid,
|
||||||
|
"denomination key for refunded coin unknown to auditor");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TALER_ARL_amount_add (&ds->denom_balance,
|
||||||
|
&ds->denom_balance,
|
||||||
|
&amount_without_fee);
|
||||||
|
TALER_ARL_amount_add (&ds->denom_risk,
|
||||||
|
&ds->denom_risk,
|
||||||
|
&amount_without_fee);
|
||||||
|
TALER_ARL_amount_add (&total_escrow_balance,
|
||||||
|
&total_escrow_balance,
|
||||||
|
&amount_without_fee);
|
||||||
|
TALER_ARL_amount_add (&total_risk,
|
||||||
|
&total_risk,
|
||||||
|
&amount_without_fee);
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||||
|
"New balance of denomination `%s' after refund is %s\n",
|
||||||
|
GNUNET_h2s (&issue->denom_hash.hash),
|
||||||
|
TALER_amount2s (&ds->denom_balance));
|
||||||
|
}
|
||||||
|
/* update total refund fee balance */
|
||||||
|
TALER_ARL_amount_add (&total_refund_fee_income,
|
||||||
|
&total_refund_fee_income,
|
||||||
|
&issue->fees.refund);
|
||||||
|
TALER_ARL_amount_subtract (&total_deposit_fee_income,
|
||||||
|
&total_deposit_fee_income,
|
||||||
|
&issue->fees.deposit);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called with details about a purse that was refunded. Adds the
|
||||||
|
* refunded amounts back to the outstanding balance of the respective
|
||||||
|
* denominations.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param rowid unique serial ID for the refund in our DB
|
||||||
|
* @param purse_pub public key of the purse
|
||||||
|
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
|
||||||
|
*/
|
||||||
|
static enum GNUNET_GenericReturnValue
|
||||||
|
purse_refund_cb (void *cls,
|
||||||
|
uint64_t rowid,
|
||||||
|
const struct TALER_PurseContractPublicKeyP *purse_pub)
|
||||||
|
{
|
||||||
|
struct CoinContext *cc = cls;
|
||||||
|
enum GNUNET_DB_QueryStatus qs;
|
||||||
|
|
||||||
|
GNUNET_assert (rowid >= ppc.last_purse_refunds_serial_id); /* should be monotonically increasing */
|
||||||
|
ppc.last_purse_refunds_serial_id = rowid + 1;
|
||||||
|
qs = TALER_ARL_edb->select_purse_deposits_by_purse (TALER_ARL_edb->cls,
|
||||||
|
purse_pub,
|
||||||
|
&purse_refund_coin_cb,
|
||||||
|
cc);
|
||||||
|
if (qs < 0)
|
||||||
|
{
|
||||||
|
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
if (TALER_ARL_do_abort ())
|
if (TALER_ARL_do_abort ())
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
@ -1934,7 +2083,7 @@ check_recoup (struct CoinContext *cc,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (GNUNET_NO == ds->was_revoked)
|
if (! ds->was_revoked)
|
||||||
{
|
{
|
||||||
/* Woopsie, we allowed recoup on non-revoked denomination!? */
|
/* Woopsie, we allowed recoup on non-revoked denomination!? */
|
||||||
TALER_ARL_report (report_bad_sig_losses,
|
TALER_ARL_report (report_bad_sig_losses,
|
||||||
@ -2233,9 +2382,131 @@ purse_deposit_cb (
|
|||||||
const struct TALER_DenominationPublicKey *denom_pub)
|
const struct TALER_DenominationPublicKey *denom_pub)
|
||||||
{
|
{
|
||||||
struct CoinContext *cc = cls;
|
struct CoinContext *cc = cls;
|
||||||
|
enum GNUNET_DB_QueryStatus qs;
|
||||||
|
struct TALER_DenominationHashP dh;
|
||||||
|
const struct TALER_EXCHANGEDB_DenominationKeyInformation *issue;
|
||||||
|
struct DenominationSummary *ds;
|
||||||
|
|
||||||
GNUNET_break (0); // FIXME: not implemented!
|
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,
|
||||||
|
&issue,
|
||||||
|
&dh);
|
||||||
|
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
|
||||||
|
{
|
||||||
|
report_row_inconsistency ("purse-deposits",
|
||||||
|
rowid,
|
||||||
|
"denomination key not found");
|
||||||
|
if (TALER_ARL_do_abort ())
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
qs = check_known_coin ("purse-deposit",
|
||||||
|
issue,
|
||||||
|
rowid,
|
||||||
|
&deposit->coin_pub,
|
||||||
|
denom_pub,
|
||||||
|
&deposit->amount);
|
||||||
|
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
|
||||||
|
{
|
||||||
|
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
||||||
|
cc->qs = qs;
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
TALER_wallet_purse_deposit_verify (
|
||||||
|
NULL != deposit->exchange_base_url
|
||||||
|
? deposit->exchange_base_url
|
||||||
|
: TALER_ARL_exchange_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 ("coin_pub",
|
||||||
|
&deposit->coin_pub)));
|
||||||
|
TALER_ARL_amount_add (&total_bad_sig_loss,
|
||||||
|
&total_bad_sig_loss,
|
||||||
|
&deposit->amount);
|
||||||
|
if (TALER_ARL_do_abort ())
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update coin's denomination balance */
|
||||||
|
ds = get_denomination_summary (cc,
|
||||||
|
issue,
|
||||||
|
&issue->denom_hash);
|
||||||
|
if (NULL == ds)
|
||||||
|
{
|
||||||
|
report_row_inconsistency ("purse-deposit",
|
||||||
|
rowid,
|
||||||
|
"denomination key for purse-deposited coin unknown to auditor");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct TALER_Amount tmp;
|
||||||
|
|
||||||
|
// FIXME: refactor: repeated logic!
|
||||||
|
if (TALER_ARL_SR_INVALID_NEGATIVE ==
|
||||||
|
TALER_ARL_amount_subtract_neg (&tmp,
|
||||||
|
&ds->denom_balance,
|
||||||
|
&deposit->amount))
|
||||||
|
{
|
||||||
|
TALER_ARL_amount_add (&ds->denom_loss,
|
||||||
|
&ds->denom_loss,
|
||||||
|
&deposit->amount);
|
||||||
|
ds->report_emergency = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ds->denom_balance = tmp;
|
||||||
|
}
|
||||||
|
if (-1 == TALER_amount_cmp (&total_escrow_balance,
|
||||||
|
&deposit->amount))
|
||||||
|
{
|
||||||
|
/* This can theoretically happen if for example the exchange
|
||||||
|
never issued any coins (i.e. escrow balance is zero), but
|
||||||
|
accepted a forged coin (i.e. emergency situation after
|
||||||
|
private key compromise). In that case, we cannot even
|
||||||
|
subtract the profit we make from the fee from the escrow
|
||||||
|
balance. Tested as part of test-auditor.sh, case #18 */
|
||||||
|
report_amount_arithmetic_inconsistency (
|
||||||
|
"subtracting purse deposit fee from escrow balance",
|
||||||
|
rowid,
|
||||||
|
&total_escrow_balance,
|
||||||
|
&deposit->amount,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TALER_ARL_amount_subtract (&total_escrow_balance,
|
||||||
|
&total_escrow_balance,
|
||||||
|
&deposit->amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||||
|
"New balance of denomination `%s' after purse deposit is %s\n",
|
||||||
|
GNUNET_h2s (&issue->denom_hash.hash),
|
||||||
|
TALER_amount2s (&ds->denom_balance));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update global deposit fees */
|
||||||
|
TALER_ARL_amount_add (&total_deposit_fee_income,
|
||||||
|
&total_deposit_fee_income,
|
||||||
|
&issue->fees.deposit);
|
||||||
|
if (TALER_ARL_do_abort ())
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2339,6 +2610,20 @@ analyze_coins (void *cls)
|
|||||||
if (0 > cc.qs)
|
if (0 > cc.qs)
|
||||||
return cc.qs;
|
return cc.qs;
|
||||||
|
|
||||||
|
/* process purse_refunds */
|
||||||
|
if (0 >
|
||||||
|
(qs = TALER_ARL_edb->select_purse_refunds_above_serial_id (
|
||||||
|
TALER_ARL_edb->cls,
|
||||||
|
ppc.last_purse_refunds_serial_id,
|
||||||
|
&purse_refund_cb,
|
||||||
|
&cc)))
|
||||||
|
{
|
||||||
|
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
||||||
|
return qs;
|
||||||
|
}
|
||||||
|
if (0 > cc.qs)
|
||||||
|
return cc.qs;
|
||||||
|
|
||||||
/* process recoups */
|
/* process recoups */
|
||||||
if (0 >
|
if (0 >
|
||||||
(qs = TALER_ARL_edb->select_recoup_refresh_above_serial_id (
|
(qs = TALER_ARL_edb->select_recoup_refresh_above_serial_id (
|
||||||
@ -2631,8 +2916,11 @@ run (void *cls,
|
|||||||
GNUNET_JSON_pack_uint64 ("start_ppc_recoup_serial_id",
|
GNUNET_JSON_pack_uint64 ("start_ppc_recoup_serial_id",
|
||||||
ppc_start.last_recoup_serial_id),
|
ppc_start.last_recoup_serial_id),
|
||||||
GNUNET_JSON_pack_uint64 ("start_ppc_recoup_refresh_serial_id",
|
GNUNET_JSON_pack_uint64 ("start_ppc_recoup_refresh_serial_id",
|
||||||
ppc_start.
|
ppc_start.last_recoup_refresh_serial_id),
|
||||||
last_recoup_refresh_serial_id),
|
GNUNET_JSON_pack_uint64 ("start_ppc_purse_deposits_serial_id",
|
||||||
|
ppc_start.last_purse_deposits_serial_id),
|
||||||
|
GNUNET_JSON_pack_uint64 ("start_ppc_purse_refunds_serial_id",
|
||||||
|
ppc_start.last_purse_refunds_serial_id),
|
||||||
GNUNET_JSON_pack_uint64 ("end_ppc_withdraw_serial_id",
|
GNUNET_JSON_pack_uint64 ("end_ppc_withdraw_serial_id",
|
||||||
ppc.last_withdraw_serial_id),
|
ppc.last_withdraw_serial_id),
|
||||||
GNUNET_JSON_pack_uint64 ("end_ppc_deposit_serial_id",
|
GNUNET_JSON_pack_uint64 ("end_ppc_deposit_serial_id",
|
||||||
@ -2645,6 +2933,10 @@ run (void *cls,
|
|||||||
ppc.last_recoup_serial_id),
|
ppc.last_recoup_serial_id),
|
||||||
GNUNET_JSON_pack_uint64 ("end_ppc_recoup_refresh_serial_id",
|
GNUNET_JSON_pack_uint64 ("end_ppc_recoup_refresh_serial_id",
|
||||||
ppc.last_recoup_refresh_serial_id),
|
ppc.last_recoup_refresh_serial_id),
|
||||||
|
GNUNET_JSON_pack_uint64 ("end_ppc_purse_deposits_serial_id",
|
||||||
|
ppc.last_purse_deposits_serial_id),
|
||||||
|
GNUNET_JSON_pack_uint64 ("end_ppc_purse_refunds_serial_id",
|
||||||
|
ppc.last_purse_refunds_serial_id),
|
||||||
TALER_JSON_pack_time_abs_human ("auditor_start_time",
|
TALER_JSON_pack_time_abs_human ("auditor_start_time",
|
||||||
start_time),
|
start_time),
|
||||||
TALER_JSON_pack_time_abs_human ("auditor_end_time",
|
TALER_JSON_pack_time_abs_human ("auditor_end_time",
|
||||||
|
@ -87,6 +87,7 @@ CREATE TABLE IF NOT EXISTS auditor_progress_coin
|
|||||||
,last_recoup_serial_id INT8 NOT NULL DEFAULT 0
|
,last_recoup_serial_id INT8 NOT NULL DEFAULT 0
|
||||||
,last_recoup_refresh_serial_id INT8 NOT NULL DEFAULT 0
|
,last_recoup_refresh_serial_id INT8 NOT NULL DEFAULT 0
|
||||||
,last_purse_deposits_serial_id INT8 NOT NULL DEFAULT 0
|
,last_purse_deposits_serial_id INT8 NOT NULL DEFAULT 0
|
||||||
|
,last_purse_refunds_serial_id INT8 NOT NULL DEFAULT 0
|
||||||
,PRIMARY KEY (master_pub)
|
,PRIMARY KEY (master_pub)
|
||||||
);
|
);
|
||||||
COMMENT ON TABLE auditor_progress_coin
|
COMMENT ON TABLE auditor_progress_coin
|
||||||
|
@ -314,8 +314,9 @@ setup_connection (struct PostgresClosure *pg)
|
|||||||
",last_recoup_serial_id=$5"
|
",last_recoup_serial_id=$5"
|
||||||
",last_recoup_refresh_serial_id=$6"
|
",last_recoup_refresh_serial_id=$6"
|
||||||
",last_purse_deposits_serial_id=$7"
|
",last_purse_deposits_serial_id=$7"
|
||||||
" WHERE master_pub=$8",
|
",last_purse_refunds_serial_id=$8"
|
||||||
8),
|
" WHERE master_pub=$9",
|
||||||
|
9),
|
||||||
/* Used in #postgres_get_auditor_progress_coin() */
|
/* Used in #postgres_get_auditor_progress_coin() */
|
||||||
GNUNET_PQ_make_prepare ("auditor_progress_select_coin",
|
GNUNET_PQ_make_prepare ("auditor_progress_select_coin",
|
||||||
"SELECT"
|
"SELECT"
|
||||||
@ -326,6 +327,7 @@ setup_connection (struct PostgresClosure *pg)
|
|||||||
",last_recoup_serial_id"
|
",last_recoup_serial_id"
|
||||||
",last_recoup_refresh_serial_id"
|
",last_recoup_refresh_serial_id"
|
||||||
",last_purse_deposits_serial_id"
|
",last_purse_deposits_serial_id"
|
||||||
|
",last_purse_refunds_serial_id"
|
||||||
" FROM auditor_progress_coin"
|
" FROM auditor_progress_coin"
|
||||||
" WHERE master_pub=$1;",
|
" WHERE master_pub=$1;",
|
||||||
1),
|
1),
|
||||||
@ -340,8 +342,9 @@ setup_connection (struct PostgresClosure *pg)
|
|||||||
",last_recoup_serial_id"
|
",last_recoup_serial_id"
|
||||||
",last_recoup_refresh_serial_id"
|
",last_recoup_refresh_serial_id"
|
||||||
",last_purse_deposits_serial_id"
|
",last_purse_deposits_serial_id"
|
||||||
") VALUES ($1,$2,$3,$4,$5,$6,$7,$8);",
|
",last_purse_refunds_serial_id"
|
||||||
8),
|
") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9);",
|
||||||
|
9),
|
||||||
/* Used in #postgres_insert_wire_auditor_account_progress() */
|
/* Used in #postgres_insert_wire_auditor_account_progress() */
|
||||||
GNUNET_PQ_make_prepare ("wire_auditor_account_progress_insert",
|
GNUNET_PQ_make_prepare ("wire_auditor_account_progress_insert",
|
||||||
"INSERT INTO wire_auditor_account_progress "
|
"INSERT INTO wire_auditor_account_progress "
|
||||||
@ -1535,6 +1538,7 @@ postgres_insert_auditor_progress_coin (
|
|||||||
GNUNET_PQ_query_param_uint64 (&ppc->last_recoup_serial_id),
|
GNUNET_PQ_query_param_uint64 (&ppc->last_recoup_serial_id),
|
||||||
GNUNET_PQ_query_param_uint64 (&ppc->last_recoup_refresh_serial_id),
|
GNUNET_PQ_query_param_uint64 (&ppc->last_recoup_refresh_serial_id),
|
||||||
GNUNET_PQ_query_param_uint64 (&ppc->last_purse_deposits_serial_id),
|
GNUNET_PQ_query_param_uint64 (&ppc->last_purse_deposits_serial_id),
|
||||||
|
GNUNET_PQ_query_param_uint64 (&ppc->last_purse_refunds_serial_id),
|
||||||
GNUNET_PQ_query_param_end
|
GNUNET_PQ_query_param_end
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1568,6 +1572,7 @@ postgres_update_auditor_progress_coin (
|
|||||||
GNUNET_PQ_query_param_uint64 (&ppc->last_recoup_serial_id),
|
GNUNET_PQ_query_param_uint64 (&ppc->last_recoup_serial_id),
|
||||||
GNUNET_PQ_query_param_uint64 (&ppc->last_recoup_refresh_serial_id),
|
GNUNET_PQ_query_param_uint64 (&ppc->last_recoup_refresh_serial_id),
|
||||||
GNUNET_PQ_query_param_uint64 (&ppc->last_purse_deposits_serial_id),
|
GNUNET_PQ_query_param_uint64 (&ppc->last_purse_deposits_serial_id),
|
||||||
|
GNUNET_PQ_query_param_uint64 (&ppc->last_purse_refunds_serial_id),
|
||||||
GNUNET_PQ_query_param_auto_from_type (master_pub),
|
GNUNET_PQ_query_param_auto_from_type (master_pub),
|
||||||
GNUNET_PQ_query_param_end
|
GNUNET_PQ_query_param_end
|
||||||
};
|
};
|
||||||
@ -1612,6 +1617,8 @@ postgres_get_auditor_progress_coin (
|
|||||||
&ppc->last_recoup_refresh_serial_id),
|
&ppc->last_recoup_refresh_serial_id),
|
||||||
GNUNET_PQ_result_spec_uint64 ("last_purse_deposits_serial_id",
|
GNUNET_PQ_result_spec_uint64 ("last_purse_deposits_serial_id",
|
||||||
&ppc->last_purse_deposits_serial_id),
|
&ppc->last_purse_deposits_serial_id),
|
||||||
|
GNUNET_PQ_result_spec_uint64 ("last_purse_refunds_serial_id",
|
||||||
|
&ppc->last_purse_refunds_serial_id),
|
||||||
GNUNET_PQ_result_spec_end
|
GNUNET_PQ_result_spec_end
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,16 +14,24 @@ pkgcfg_DATA = \
|
|||||||
|
|
||||||
sqldir = $(prefix)/share/taler/sql/exchange/
|
sqldir = $(prefix)/share/taler/sql/exchange/
|
||||||
|
|
||||||
|
sqlinputs = \
|
||||||
|
common-0001.sql \
|
||||||
|
drop-common.sql \
|
||||||
|
exchange-0001-part.sql \
|
||||||
|
drop0001-exchange-part.sql \
|
||||||
|
shard-0001-part.sql \
|
||||||
|
drop0001-shard-part.sql
|
||||||
|
|
||||||
sql_DATA = \
|
sql_DATA = \
|
||||||
benchmark-0000.sql \
|
benchmark-0000.sql \
|
||||||
benchmark-0001.sql \
|
benchmark-0001.sql \
|
||||||
exchange-0000.sql \
|
exchange-0000.sql \
|
||||||
exchange-0001-part.sql \
|
exchange-0001.sql \
|
||||||
shard-0001-part.sql \
|
drop0001.sql \
|
||||||
common-0001.sql \
|
shard-0000.sql \
|
||||||
drop-common.sql \
|
shard-0001.sql \
|
||||||
drop0001-exchange-part.sql \
|
shard-drop0001.sql
|
||||||
drop0001-shard-part.sql
|
|
||||||
|
|
||||||
BUILT_SOURCES = \
|
BUILT_SOURCES = \
|
||||||
shard-0000.sql \
|
shard-0000.sql \
|
||||||
@ -40,22 +48,27 @@ CLEANFILES = \
|
|||||||
shard-drop0001.sql
|
shard-drop0001.sql
|
||||||
|
|
||||||
exchange-0001.sql: common-0001.sql exchange-0001-part.sql
|
exchange-0001.sql: common-0001.sql exchange-0001-part.sql
|
||||||
|
chmod +w $@ || true
|
||||||
cat common-0001.sql exchange-0001-part.sql >$@
|
cat common-0001.sql exchange-0001-part.sql >$@
|
||||||
chmod -w $@
|
chmod -w $@
|
||||||
|
|
||||||
shard-0001.sql: common-0001.sql shard-0001-part.sql
|
shard-0001.sql: common-0001.sql shard-0001-part.sql
|
||||||
|
chmod +w $@ || true
|
||||||
cat common-0001.sql shard-0001-part.sql >$@
|
cat common-0001.sql shard-0001-part.sql >$@
|
||||||
chmod -w $@
|
chmod -w $@
|
||||||
|
|
||||||
shard-0000.sql: exchange-0000.sql
|
shard-0000.sql: exchange-0000.sql
|
||||||
|
chmod +w $@ || true
|
||||||
cp exchange-0000.sql $@
|
cp exchange-0000.sql $@
|
||||||
chmod -w $@
|
chmod -w $@
|
||||||
|
|
||||||
drop0001.sql: drop-common.sql drop0001-exchange-part.sql
|
drop0001.sql: drop-common.sql drop0001-exchange-part.sql
|
||||||
|
chmod +w $@ || true
|
||||||
cat drop-common.sql drop0001-exchange-part.sql >$@
|
cat drop-common.sql drop0001-exchange-part.sql >$@
|
||||||
chmod -w $@
|
chmod -w $@
|
||||||
|
|
||||||
shard-drop0001.sql: drop-common.sql drop0001-shard-part.sql
|
shard-drop0001.sql: drop-common.sql drop0001-shard-part.sql
|
||||||
|
chmod +w $@ || true
|
||||||
cat drop-common.sql drop0001-shard-part.sql >$@
|
cat drop-common.sql drop0001-shard-part.sql >$@
|
||||||
chmod -w $@
|
chmod -w $@
|
||||||
|
|
||||||
@ -67,6 +80,7 @@ EXTRA_DIST = \
|
|||||||
lrbt_callbacks.c \
|
lrbt_callbacks.c \
|
||||||
bench-db-postgres.conf \
|
bench-db-postgres.conf \
|
||||||
test-exchange-db-postgres.conf \
|
test-exchange-db-postgres.conf \
|
||||||
|
$(sqlinputs) \
|
||||||
$(sql_DATA)
|
$(sql_DATA)
|
||||||
|
|
||||||
plugindir = $(libdir)/taler
|
plugindir = $(libdir)/taler
|
||||||
|
@ -1219,6 +1219,54 @@ BEGIN
|
|||||||
END
|
END
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------- purse_refunds ----------------------------------------
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION create_table_purse_refunds(
|
||||||
|
IN shard_suffix VARCHAR DEFAULT NULL
|
||||||
|
)
|
||||||
|
RETURNS VOID
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
AS $$
|
||||||
|
DECLARE
|
||||||
|
table_name VARCHAR DEFAULT 'purse_refunds';
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
PERFORM create_partitioned_table(
|
||||||
|
'CREATE TABLE IF NOT EXISTS %I '
|
||||||
|
'(purse_refunds_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY' --UNIQUE
|
||||||
|
',purse_pub BYTEA NOT NULL CHECK (LENGTH(purse_pub)=32)'
|
||||||
|
',PRIMARY KEY (purse_pub)'
|
||||||
|
') %s ;'
|
||||||
|
,table_name
|
||||||
|
,'PARTITION BY HASH (purse_pub)'
|
||||||
|
,shard_suffix
|
||||||
|
);
|
||||||
|
|
||||||
|
table_name = concat_ws('_', table_name, shard_suffix);
|
||||||
|
|
||||||
|
END
|
||||||
|
$$;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION add_constraints_to_purse_refunds_partition(
|
||||||
|
IN partition_suffix VARCHAR
|
||||||
|
)
|
||||||
|
RETURNS VOID
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
AS $$
|
||||||
|
BEGIN
|
||||||
|
EXECUTE FORMAT (
|
||||||
|
'ALTER TABLE purse_refunds_' || partition_suffix || ' '
|
||||||
|
'ADD CONSTRAINT purse_refunds_' || partition_suffix || '_purse_refunds_serial_id_key '
|
||||||
|
'UNIQUE (purse_refunds_serial_id) '
|
||||||
|
);
|
||||||
|
END
|
||||||
|
$$;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
---------------------------- purse_merges -----------------------------
|
---------------------------- purse_merges -----------------------------
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION create_table_purse_merges(
|
CREATE OR REPLACE FUNCTION create_table_purse_merges(
|
||||||
@ -1828,6 +1876,9 @@ BEGIN
|
|||||||
ALTER TABLE IF EXISTS purse_requests
|
ALTER TABLE IF EXISTS purse_requests
|
||||||
DETACH partition purse_requests_default;
|
DETACH partition purse_requests_default;
|
||||||
|
|
||||||
|
ALTER TABLE IF EXISTS purse_refunds
|
||||||
|
DETACH partition purse_refunds_default;
|
||||||
|
|
||||||
ALTER TABLE IF EXISTS purse_merges
|
ALTER TABLE IF EXISTS purse_merges
|
||||||
DETACH partition purse_merges_default;
|
DETACH partition purse_merges_default;
|
||||||
|
|
||||||
@ -1894,6 +1945,7 @@ BEGIN
|
|||||||
DROP TABLE IF EXISTS cs_nonce_locks_default;
|
DROP TABLE IF EXISTS cs_nonce_locks_default;
|
||||||
|
|
||||||
DROP TABLE IF EXISTS purse_requests_default;
|
DROP TABLE IF EXISTS purse_requests_default;
|
||||||
|
DROP TABLE IF EXISTS purse_refunds_default;
|
||||||
DROP TABLE IF EXISTS purse_merges_default;
|
DROP TABLE IF EXISTS purse_merges_default;
|
||||||
DROP TABLE IF EXISTS account_merges_default;
|
DROP TABLE IF EXISTS account_merges_default;
|
||||||
DROP TABLE IF EXISTS contracts_default;
|
DROP TABLE IF EXISTS contracts_default;
|
||||||
@ -2105,6 +2157,13 @@ BEGIN
|
|||||||
);
|
);
|
||||||
PERFORM add_constraints_to_purse_requests_partition(num_partitions::varchar);
|
PERFORM add_constraints_to_purse_requests_partition(num_partitions::varchar);
|
||||||
|
|
||||||
|
PERFORM create_hash_partition(
|
||||||
|
'purse_refunds'
|
||||||
|
,modulus
|
||||||
|
,num_partitions
|
||||||
|
);
|
||||||
|
PERFORM add_constraints_to_purse_refunds_partition(num_partitions::varchar);
|
||||||
|
|
||||||
PERFORM create_hash_partition(
|
PERFORM create_hash_partition(
|
||||||
'purse_merges'
|
'purse_merges'
|
||||||
,modulus
|
,modulus
|
||||||
@ -2316,6 +2375,10 @@ BEGIN
|
|||||||
DROP CONSTRAINT IF EXISTS purse_requests_pkey CASCADE
|
DROP CONSTRAINT IF EXISTS purse_requests_pkey CASCADE
|
||||||
;
|
;
|
||||||
|
|
||||||
|
ALTER TABLE IF EXISTS purse_refunds
|
||||||
|
DROP CONSTRAINT IF EXISTS purse_refunds_pkey CASCADE
|
||||||
|
;
|
||||||
|
|
||||||
ALTER TABLE IF EXISTS purse_merges
|
ALTER TABLE IF EXISTS purse_merges
|
||||||
DROP CONSTRAINT IF EXISTS purse_merges_pkey CASCADE
|
DROP CONSTRAINT IF EXISTS purse_merges_pkey CASCADE
|
||||||
;
|
;
|
||||||
@ -2571,6 +2634,13 @@ BEGIN
|
|||||||
,current_shard_num
|
,current_shard_num
|
||||||
,local_user
|
,local_user
|
||||||
);
|
);
|
||||||
|
PERFORM create_foreign_hash_partition(
|
||||||
|
'purse_refunds'
|
||||||
|
,total_num_shards
|
||||||
|
,shard_suffix
|
||||||
|
,current_shard_num
|
||||||
|
,local_user
|
||||||
|
);
|
||||||
PERFORM create_foreign_hash_partition(
|
PERFORM create_foreign_hash_partition(
|
||||||
'purse_merges'
|
'purse_merges'
|
||||||
,total_num_shards
|
,total_num_shards
|
||||||
|
@ -63,6 +63,8 @@ DROP FUNCTION IF EXISTS add_constraints_to_cs_nonce_locks_partition;
|
|||||||
|
|
||||||
DROP FUNCTION IF EXISTS create_table_purse_requests;
|
DROP FUNCTION IF EXISTS create_table_purse_requests;
|
||||||
DROP FUNCTION IF EXISTS add_constraints_to_purse_requests_partition;
|
DROP FUNCTION IF EXISTS add_constraints_to_purse_requests_partition;
|
||||||
|
DROP FUNCTION IF EXISTS create_table_purse_refunds;
|
||||||
|
DROP FUNCTION IF EXISTS add_constraints_to_purse_refunds_partition;
|
||||||
DROP FUNCTION IF EXISTS create_table_purse_merges;
|
DROP FUNCTION IF EXISTS create_table_purse_merges;
|
||||||
DROP FUNCTION IF EXISTS add_constraints_to_purse_merges_partition;
|
DROP FUNCTION IF EXISTS add_constraints_to_purse_merges_partition;
|
||||||
DROP FUNCTION IF EXISTS create_table_account_merges;
|
DROP FUNCTION IF EXISTS create_table_account_merges;
|
||||||
|
@ -73,6 +73,7 @@ DROP TABLE IF EXISTS contracts CASCADE;
|
|||||||
DROP TABLE IF EXISTS history_requests CASCADE;
|
DROP TABLE IF EXISTS history_requests CASCADE;
|
||||||
DROP TABLE IF EXISTS close_requests CASCADE;
|
DROP TABLE IF EXISTS close_requests CASCADE;
|
||||||
DROP TABLE IF EXISTS purse_requests CASCADE;
|
DROP TABLE IF EXISTS purse_requests CASCADE;
|
||||||
|
DROP TABLE IF EXISTS purse_refunds CASCADE;
|
||||||
DROP TABLE IF EXISTS wads_out CASCADE;
|
DROP TABLE IF EXISTS wads_out CASCADE;
|
||||||
DROP TABLE IF EXISTS wad_out_entries CASCADE;
|
DROP TABLE IF EXISTS wad_out_entries CASCADE;
|
||||||
DROP TABLE IF EXISTS wads_in CASCADE;
|
DROP TABLE IF EXISTS wads_in CASCADE;
|
||||||
|
@ -1040,6 +1040,21 @@ CREATE TABLE IF NOT EXISTS purse_requests_default
|
|||||||
SELECT add_constraints_to_purse_requests_partition('default');
|
SELECT add_constraints_to_purse_requests_partition('default');
|
||||||
|
|
||||||
|
|
||||||
|
-- ------------------------------ purse_refunds ----------------------------------------
|
||||||
|
|
||||||
|
SELECT create_table_purse_refunds();
|
||||||
|
|
||||||
|
COMMENT ON TABLE purse_refunds
|
||||||
|
IS 'Purses that were refunded due to expiration';
|
||||||
|
COMMENT ON COLUMN purse_refunds.purse_pub
|
||||||
|
IS 'Public key of the purse';
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS purse_refunds_default
|
||||||
|
PARTITION OF purse_refunds
|
||||||
|
FOR VALUES WITH (MODULUS 1, REMAINDER 0);
|
||||||
|
|
||||||
|
SELECT add_constraints_to_purse_refunds_partition('default');
|
||||||
|
|
||||||
|
|
||||||
-- ------------------------------ purse_merges ----------------------------------------
|
-- ------------------------------ purse_merges ----------------------------------------
|
||||||
|
|
||||||
@ -3485,6 +3500,11 @@ UPDATE purse_requests
|
|||||||
finished=TRUE
|
finished=TRUE
|
||||||
WHERE purse_pub=my_purse_pub;
|
WHERE purse_pub=my_purse_pub;
|
||||||
|
|
||||||
|
INSERT INTO purse_refunds
|
||||||
|
(purse_pub)
|
||||||
|
VALUES
|
||||||
|
(my_purse_pub);
|
||||||
|
|
||||||
-- restore balance to each coin deposited into the purse
|
-- restore balance to each coin deposited into the purse
|
||||||
FOR my_deposit IN
|
FOR my_deposit IN
|
||||||
SELECT coin_pub
|
SELECT coin_pub
|
||||||
|
@ -809,6 +809,8 @@ irbt_cb_table_purse_requests (struct PostgresClosure *pg,
|
|||||||
{
|
{
|
||||||
struct GNUNET_PQ_QueryParam params[] = {
|
struct GNUNET_PQ_QueryParam params[] = {
|
||||||
GNUNET_PQ_query_param_uint64 (&td->serial),
|
GNUNET_PQ_query_param_uint64 (&td->serial),
|
||||||
|
GNUNET_PQ_query_param_auto_from_type (
|
||||||
|
&td->details.purse_requests.purse_pub),
|
||||||
GNUNET_PQ_query_param_auto_from_type (
|
GNUNET_PQ_query_param_auto_from_type (
|
||||||
&td->details.purse_requests.merge_pub),
|
&td->details.purse_requests.merge_pub),
|
||||||
GNUNET_PQ_query_param_timestamp (
|
GNUNET_PQ_query_param_timestamp (
|
||||||
@ -832,6 +834,29 @@ irbt_cb_table_purse_requests (struct PostgresClosure *pg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called with purse_refunds records to insert into table.
|
||||||
|
*
|
||||||
|
* @param pg plugin context
|
||||||
|
* @param td record to insert
|
||||||
|
*/
|
||||||
|
static enum GNUNET_DB_QueryStatus
|
||||||
|
irbt_cb_table_purse_refunds (struct PostgresClosure *pg,
|
||||||
|
const struct TALER_EXCHANGEDB_TableData *td)
|
||||||
|
{
|
||||||
|
struct GNUNET_PQ_QueryParam params[] = {
|
||||||
|
GNUNET_PQ_query_param_uint64 (&td->serial),
|
||||||
|
GNUNET_PQ_query_param_auto_from_type (
|
||||||
|
&td->details.purse_refunds.purse_pub),
|
||||||
|
GNUNET_PQ_query_param_end
|
||||||
|
};
|
||||||
|
|
||||||
|
return GNUNET_PQ_eval_prepared_non_select (pg->conn,
|
||||||
|
"insert_into_table_purse_refunds",
|
||||||
|
params);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function called with purse_merges records to insert into table.
|
* Function called with purse_merges records to insert into table.
|
||||||
*
|
*
|
||||||
|
@ -1549,6 +1549,51 @@ lrbt_cb_table_purse_requests (void *cls,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called with purse_refunds table entries.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param result the postgres result
|
||||||
|
* @param num_results the number of results in @a result
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
lrbt_cb_table_purse_refunds (void *cls,
|
||||||
|
PGresult *result,
|
||||||
|
unsigned int num_results)
|
||||||
|
{
|
||||||
|
struct LookupRecordsByTableContext *ctx = cls;
|
||||||
|
struct TALER_EXCHANGEDB_TableData td = {
|
||||||
|
.table = TALER_EXCHANGEDB_RT_PURSE_REFUNDS
|
||||||
|
};
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i<num_results; i++)
|
||||||
|
{
|
||||||
|
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||||
|
GNUNET_PQ_result_spec_uint64 (
|
||||||
|
"purse_refunds_serial_id",
|
||||||
|
&td.serial),
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type (
|
||||||
|
"purse_pub",
|
||||||
|
&td.details.purse_refunds.purse_pub),
|
||||||
|
GNUNET_PQ_result_spec_end
|
||||||
|
};
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_PQ_extract_result (result,
|
||||||
|
rs,
|
||||||
|
i))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
ctx->error = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ctx->cb (ctx->cb_cls,
|
||||||
|
&td);
|
||||||
|
GNUNET_PQ_cleanup_result (rs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function called with purse_merges table entries.
|
* Function called with purse_merges table entries.
|
||||||
*
|
*
|
||||||
|
@ -1407,6 +1407,19 @@ prepare_statements (struct PostgresClosure *pg)
|
|||||||
" WHERE ref.refund_serial_id>=$1"
|
" WHERE ref.refund_serial_id>=$1"
|
||||||
" ORDER BY ref.refund_serial_id ASC;",
|
" ORDER BY ref.refund_serial_id ASC;",
|
||||||
1),
|
1),
|
||||||
|
GNUNET_PQ_make_prepare (
|
||||||
|
"test_refund_full",
|
||||||
|
"SELECT"
|
||||||
|
" CAST(SUM(CAST(ref.amount_with_fee_frac AS INT8)) AS INT8) AS s_f"
|
||||||
|
",CAST(SUM(ref.amount_with_fee_val) AS INT8) AS s_v"
|
||||||
|
",dep.amount_with_fee_val"
|
||||||
|
",dep.amount_with_fee_frac"
|
||||||
|
" FROM refunds ref"
|
||||||
|
" JOIN deposits dep"
|
||||||
|
" ON (ref.coin_pub=dep.coin_pub AND ref.deposit_serial_id=dep.deposit_serial_id)"
|
||||||
|
" WHERE ref.refund_serial_id=$1"
|
||||||
|
" GROUP BY (dep.amount_with_fee_val, dep.amount_with_fee_frac);",
|
||||||
|
1),
|
||||||
|
|
||||||
/* Store information about a /deposit the exchange is to execute.
|
/* Store information about a /deposit the exchange is to execute.
|
||||||
Used in #postgres_insert_deposit(). Only used in test cases. */
|
Used in #postgres_insert_deposit(). Only used in test cases. */
|
||||||
@ -1508,6 +1521,29 @@ prepare_statements (struct PostgresClosure *pg)
|
|||||||
" )"
|
" )"
|
||||||
" ORDER BY purse_deposit_serial_id ASC;",
|
" ORDER BY purse_deposit_serial_id ASC;",
|
||||||
1),
|
1),
|
||||||
|
GNUNET_PQ_make_prepare (
|
||||||
|
"audit_get_purse_deposits_by_purse",
|
||||||
|
"SELECT"
|
||||||
|
" pd.amount_with_fee_val"
|
||||||
|
",pd.amount_with_fee_frac"
|
||||||
|
",pd.coin_pub"
|
||||||
|
",denom.denom_pub"
|
||||||
|
" FROM purse_deposits pd"
|
||||||
|
" JOIN known_coins kc USING (coin_pub)"
|
||||||
|
" JOIN denominations denom USING (denominations_serial)"
|
||||||
|
" WHERE purse_pub=$1;",
|
||||||
|
1),
|
||||||
|
GNUNET_PQ_make_prepare (
|
||||||
|
"audit_get_purse_refunds_incr",
|
||||||
|
"SELECT"
|
||||||
|
" purse_pub"
|
||||||
|
",purse_refunds_serial_id"
|
||||||
|
" FROM purse_refunds"
|
||||||
|
" WHERE ("
|
||||||
|
" (purse_refunds_serial_id>=$1)"
|
||||||
|
" )"
|
||||||
|
" ORDER BY purse_refunds_serial_id ASC;",
|
||||||
|
1),
|
||||||
/* Fetch an existing deposit request.
|
/* Fetch an existing deposit request.
|
||||||
Used in #postgres_lookup_transfer_by_deposit(). */
|
Used in #postgres_lookup_transfer_by_deposit(). */
|
||||||
GNUNET_PQ_make_prepare (
|
GNUNET_PQ_make_prepare (
|
||||||
@ -2778,6 +2814,14 @@ prepare_statements (struct PostgresClosure *pg)
|
|||||||
" ORDER BY purse_requests_serial_id DESC"
|
" ORDER BY purse_requests_serial_id DESC"
|
||||||
" LIMIT 1;",
|
" LIMIT 1;",
|
||||||
0),
|
0),
|
||||||
|
GNUNET_PQ_make_prepare (
|
||||||
|
"select_serial_by_table_purse_refunds",
|
||||||
|
"SELECT"
|
||||||
|
" purse_refunds_serial_id AS serial"
|
||||||
|
" FROM purse_refunds"
|
||||||
|
" ORDER BY purse_refunds_serial_id DESC"
|
||||||
|
" LIMIT 1;",
|
||||||
|
0),
|
||||||
GNUNET_PQ_make_prepare (
|
GNUNET_PQ_make_prepare (
|
||||||
"select_serial_by_table_purse_merges",
|
"select_serial_by_table_purse_merges",
|
||||||
"SELECT"
|
"SELECT"
|
||||||
@ -3212,6 +3256,15 @@ prepare_statements (struct PostgresClosure *pg)
|
|||||||
" WHERE purse_requests_serial_id > $1"
|
" WHERE purse_requests_serial_id > $1"
|
||||||
" ORDER BY purse_requests_serial_id ASC;",
|
" ORDER BY purse_requests_serial_id ASC;",
|
||||||
1),
|
1),
|
||||||
|
GNUNET_PQ_make_prepare (
|
||||||
|
"select_above_serial_by_table_purse_refunds",
|
||||||
|
"SELECT"
|
||||||
|
" purse_refunds_serial_id"
|
||||||
|
",purse_pub"
|
||||||
|
" FROM purse_refunds"
|
||||||
|
" WHERE purse_refunds_serial_id > $1"
|
||||||
|
" ORDER BY purse_refunds_serial_id ASC;",
|
||||||
|
1),
|
||||||
GNUNET_PQ_make_prepare (
|
GNUNET_PQ_make_prepare (
|
||||||
"select_above_serial_by_table_purse_merges",
|
"select_above_serial_by_table_purse_merges",
|
||||||
"SELECT"
|
"SELECT"
|
||||||
@ -3688,6 +3741,14 @@ prepare_statements (struct PostgresClosure *pg)
|
|||||||
") VALUES "
|
") VALUES "
|
||||||
"($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13);",
|
"($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13);",
|
||||||
13),
|
13),
|
||||||
|
GNUNET_PQ_make_prepare (
|
||||||
|
"insert_into_table_purse_refunds",
|
||||||
|
"INSERT INTO purse_refunds"
|
||||||
|
"(purse_refunds_serial_id"
|
||||||
|
",purse_pub"
|
||||||
|
") VALUES "
|
||||||
|
"($1, $2);",
|
||||||
|
2),
|
||||||
GNUNET_PQ_make_prepare (
|
GNUNET_PQ_make_prepare (
|
||||||
"insert_into_table_purse_merges",
|
"insert_into_table_purse_merges",
|
||||||
"INSERT INTO purse_merges"
|
"INSERT INTO purse_merges"
|
||||||
@ -10496,6 +10557,242 @@ postgres_select_purse_deposits_above_serial_id (
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closure for #purse_refund_serial_helper_cb().
|
||||||
|
*/
|
||||||
|
struct PurseRefundSerialContext
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to call.
|
||||||
|
*/
|
||||||
|
TALER_EXCHANGEDB_PurseRefundCallback 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 PurseRefundSerialContext`
|
||||||
|
* @param result the postgres result
|
||||||
|
* @param num_results the number of results in @a result
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
purse_refund_serial_helper_cb (void *cls,
|
||||||
|
PGresult *result,
|
||||||
|
unsigned int num_results)
|
||||||
|
{
|
||||||
|
struct PurseRefundSerialContext *dsc = cls;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i<num_results; i++)
|
||||||
|
{
|
||||||
|
struct TALER_PurseContractPublicKeyP purse_pub;
|
||||||
|
uint64_t rowid;
|
||||||
|
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type ("purse_pub",
|
||||||
|
&purse_pub),
|
||||||
|
GNUNET_PQ_result_spec_uint64 ("purse_deposit_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;
|
||||||
|
}
|
||||||
|
ret = dsc->cb (dsc->cb_cls,
|
||||||
|
rowid,
|
||||||
|
&purse_pub);
|
||||||
|
GNUNET_PQ_cleanup_result (rs);
|
||||||
|
if (GNUNET_OK != ret)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select purse refunds above @a serial_id in monotonically increasing
|
||||||
|
* order.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param serial_id highest serial ID to exclude (select strictly larger)
|
||||||
|
* @param cb function to call on each result
|
||||||
|
* @param cb_cls closure for @a cb
|
||||||
|
* @return transaction status code
|
||||||
|
*/
|
||||||
|
static enum GNUNET_DB_QueryStatus
|
||||||
|
postgres_select_purse_refunds_above_serial_id (
|
||||||
|
void *cls,
|
||||||
|
uint64_t serial_id,
|
||||||
|
TALER_EXCHANGEDB_PurseRefundCallback cb,
|
||||||
|
void *cb_cls)
|
||||||
|
{
|
||||||
|
struct PostgresClosure *pg = cls;
|
||||||
|
struct GNUNET_PQ_QueryParam params[] = {
|
||||||
|
GNUNET_PQ_query_param_uint64 (&serial_id),
|
||||||
|
GNUNET_PQ_query_param_end
|
||||||
|
};
|
||||||
|
struct PurseRefundSerialContext 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_refunds_incr",
|
||||||
|
params,
|
||||||
|
&purse_refund_serial_helper_cb,
|
||||||
|
&dsc);
|
||||||
|
if (GNUNET_OK != dsc.status)
|
||||||
|
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||||
|
return qs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closure for #purse_refund_coin_helper_cb().
|
||||||
|
*/
|
||||||
|
struct PurseRefundCoinContext
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to call.
|
||||||
|
*/
|
||||||
|
TALER_EXCHANGEDB_PurseRefundCoinCallback 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 PurseRefundCoinContext`
|
||||||
|
* @param result the postgres result
|
||||||
|
* @param num_results the number of results in @a result
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
purse_refund_coin_helper_cb (void *cls,
|
||||||
|
PGresult *result,
|
||||||
|
unsigned int num_results)
|
||||||
|
{
|
||||||
|
struct PurseRefundCoinContext *dsc = cls;
|
||||||
|
struct PostgresClosure *pg = dsc->pg;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i<num_results; i++)
|
||||||
|
{
|
||||||
|
struct TALER_Amount amount_with_fee;
|
||||||
|
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||||
|
struct TALER_DenominationPublicKey denom_pub;
|
||||||
|
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||||
|
TALER_PQ_result_spec_denom_pub ("denom_pub",
|
||||||
|
&denom_pub),
|
||||||
|
TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
|
||||||
|
&amount_with_fee),
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
|
||||||
|
&coin_pub),
|
||||||
|
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,
|
||||||
|
&amount_with_fee,
|
||||||
|
&coin_pub,
|
||||||
|
&denom_pub);
|
||||||
|
GNUNET_PQ_cleanup_result (rs);
|
||||||
|
if (GNUNET_OK != ret)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select coin affected by purse refund.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param purse_pub purse that was refunded
|
||||||
|
* @param cb function to call on each result
|
||||||
|
* @param cb_cls closure for @a cb
|
||||||
|
* @return transaction status code
|
||||||
|
*/
|
||||||
|
static enum GNUNET_DB_QueryStatus
|
||||||
|
postgres_select_purse_deposits_by_purse (
|
||||||
|
void *cls,
|
||||||
|
const struct TALER_PurseContractPublicKeyP *purse_pub,
|
||||||
|
TALER_EXCHANGEDB_PurseRefundCoinCallback cb,
|
||||||
|
void *cb_cls)
|
||||||
|
{
|
||||||
|
struct PostgresClosure *pg = cls;
|
||||||
|
struct GNUNET_PQ_QueryParam params[] = {
|
||||||
|
GNUNET_PQ_query_param_auto_from_type (purse_pub),
|
||||||
|
GNUNET_PQ_query_param_end
|
||||||
|
};
|
||||||
|
struct PurseRefundCoinContext 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_deposits_by_purse",
|
||||||
|
params,
|
||||||
|
&purse_refund_coin_helper_cb,
|
||||||
|
&dsc);
|
||||||
|
if (GNUNET_OK != dsc.status)
|
||||||
|
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||||
|
return qs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closure for #refreshs_serial_helper_cb().
|
* Closure for #refreshs_serial_helper_cb().
|
||||||
*/
|
*/
|
||||||
@ -10690,6 +10987,7 @@ refunds_serial_helper_cb (void *cls,
|
|||||||
struct TALER_EXCHANGEDB_Refund refund;
|
struct TALER_EXCHANGEDB_Refund refund;
|
||||||
struct TALER_DenominationPublicKey denom_pub;
|
struct TALER_DenominationPublicKey denom_pub;
|
||||||
uint64_t rowid;
|
uint64_t rowid;
|
||||||
|
bool full_refund;
|
||||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||||
GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
|
GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
|
||||||
&refund.details.merchant_pub),
|
&refund.details.merchant_pub),
|
||||||
@ -10720,6 +11018,42 @@ refunds_serial_helper_cb (void *cls,
|
|||||||
rsc->status = GNUNET_SYSERR;
|
rsc->status = GNUNET_SYSERR;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
struct GNUNET_PQ_QueryParam params[] = {
|
||||||
|
GNUNET_PQ_query_param_uint64 (&rowid),
|
||||||
|
GNUNET_PQ_query_param_end
|
||||||
|
};
|
||||||
|
struct TALER_Amount amount_with_fee;
|
||||||
|
uint64_t s_f;
|
||||||
|
uint64_t s_v;
|
||||||
|
struct GNUNET_PQ_ResultSpec rs2[] = {
|
||||||
|
GNUNET_PQ_result_spec_uint64 ("s_v",
|
||||||
|
&s_v),
|
||||||
|
GNUNET_PQ_result_spec_uint64 ("s_f",
|
||||||
|
&s_f),
|
||||||
|
TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
|
||||||
|
&amount_with_fee),
|
||||||
|
GNUNET_PQ_result_spec_end
|
||||||
|
};
|
||||||
|
enum GNUNET_DB_QueryStatus qs;
|
||||||
|
|
||||||
|
qs = GNUNET_PQ_eval_prepared_singleton_select (
|
||||||
|
pg->conn,
|
||||||
|
"test_refund_full",
|
||||||
|
params,
|
||||||
|
rs2);
|
||||||
|
if (qs <= 0)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
rsc->status = GNUNET_SYSERR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* normalize */
|
||||||
|
s_v += s_f / TALER_AMOUNT_FRAC_BASE;
|
||||||
|
s_f %= TALER_AMOUNT_FRAC_BASE;
|
||||||
|
full_refund = (s_v >= amount_with_fee.value) &&
|
||||||
|
(s_f >= amount_with_fee.fraction);
|
||||||
|
}
|
||||||
ret = rsc->cb (rsc->cb_cls,
|
ret = rsc->cb (rsc->cb_cls,
|
||||||
rowid,
|
rowid,
|
||||||
&denom_pub,
|
&denom_pub,
|
||||||
@ -10728,6 +11062,7 @@ refunds_serial_helper_cb (void *cls,
|
|||||||
&refund.details.merchant_sig,
|
&refund.details.merchant_sig,
|
||||||
&refund.details.h_contract_terms,
|
&refund.details.h_contract_terms,
|
||||||
refund.details.rtransaction_id,
|
refund.details.rtransaction_id,
|
||||||
|
full_refund,
|
||||||
&refund.details.refund_amount);
|
&refund.details.refund_amount);
|
||||||
GNUNET_PQ_cleanup_result (rs);
|
GNUNET_PQ_cleanup_result (rs);
|
||||||
if (GNUNET_OK != ret)
|
if (GNUNET_OK != ret)
|
||||||
@ -13129,6 +13464,9 @@ postgres_lookup_serial_by_table (void *cls,
|
|||||||
case TALER_EXCHANGEDB_RT_PURSE_REQUESTS:
|
case TALER_EXCHANGEDB_RT_PURSE_REQUESTS:
|
||||||
statement = "select_serial_by_table_purse_requests";
|
statement = "select_serial_by_table_purse_requests";
|
||||||
break;
|
break;
|
||||||
|
case TALER_EXCHANGEDB_RT_PURSE_REFUNDS:
|
||||||
|
statement = "select_serial_by_table_purse_refunds";
|
||||||
|
break;
|
||||||
case TALER_EXCHANGEDB_RT_PURSE_MERGES:
|
case TALER_EXCHANGEDB_RT_PURSE_MERGES:
|
||||||
statement = "select_serial_by_table_purse_merges";
|
statement = "select_serial_by_table_purse_merges";
|
||||||
break;
|
break;
|
||||||
@ -13337,6 +13675,10 @@ postgres_lookup_records_by_table (void *cls,
|
|||||||
statement = "select_above_serial_by_table_purse_requests";
|
statement = "select_above_serial_by_table_purse_requests";
|
||||||
rh = &lrbt_cb_table_purse_requests;
|
rh = &lrbt_cb_table_purse_requests;
|
||||||
break;
|
break;
|
||||||
|
case TALER_EXCHANGEDB_RT_PURSE_REFUNDS:
|
||||||
|
statement = "select_above_serial_by_table_purse_refunds";
|
||||||
|
rh = &lrbt_cb_table_purse_refunds;
|
||||||
|
break;
|
||||||
case TALER_EXCHANGEDB_RT_PURSE_MERGES:
|
case TALER_EXCHANGEDB_RT_PURSE_MERGES:
|
||||||
statement = "select_above_serial_by_table_purse_merges";
|
statement = "select_above_serial_by_table_purse_merges";
|
||||||
rh = &lrbt_cb_table_purse_merges;
|
rh = &lrbt_cb_table_purse_merges;
|
||||||
@ -13510,6 +13852,9 @@ postgres_insert_records_by_table (void *cls,
|
|||||||
case TALER_EXCHANGEDB_RT_PURSE_REQUESTS:
|
case TALER_EXCHANGEDB_RT_PURSE_REQUESTS:
|
||||||
rh = &irbt_cb_table_purse_requests;
|
rh = &irbt_cb_table_purse_requests;
|
||||||
break;
|
break;
|
||||||
|
case TALER_EXCHANGEDB_RT_PURSE_REFUNDS:
|
||||||
|
rh = &irbt_cb_table_purse_refunds;
|
||||||
|
break;
|
||||||
case TALER_EXCHANGEDB_RT_PURSE_MERGES:
|
case TALER_EXCHANGEDB_RT_PURSE_MERGES:
|
||||||
rh = &irbt_cb_table_purse_merges;
|
rh = &irbt_cb_table_purse_merges;
|
||||||
break;
|
break;
|
||||||
@ -15203,6 +15548,10 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
|
|||||||
= &postgres_select_deposits_above_serial_id;
|
= &postgres_select_deposits_above_serial_id;
|
||||||
plugin->select_purse_deposits_above_serial_id
|
plugin->select_purse_deposits_above_serial_id
|
||||||
= &postgres_select_purse_deposits_above_serial_id;
|
= &postgres_select_purse_deposits_above_serial_id;
|
||||||
|
plugin->select_purse_refunds_above_serial_id
|
||||||
|
= &postgres_select_purse_refunds_above_serial_id;
|
||||||
|
plugin->select_purse_deposits_by_purse
|
||||||
|
= &postgres_select_purse_deposits_by_purse;
|
||||||
plugin->select_refreshes_above_serial_id
|
plugin->select_refreshes_above_serial_id
|
||||||
= &postgres_select_refreshes_above_serial_id;
|
= &postgres_select_refreshes_above_serial_id;
|
||||||
plugin->select_refunds_above_serial_id
|
plugin->select_refunds_above_serial_id
|
||||||
|
@ -92,6 +92,9 @@ BEGIN
|
|||||||
PERFORM create_table_purse_requests(shard_suffix);
|
PERFORM create_table_purse_requests(shard_suffix);
|
||||||
PERFORM add_constraints_to_purse_requests_partition(shard_suffix);
|
PERFORM add_constraints_to_purse_requests_partition(shard_suffix);
|
||||||
|
|
||||||
|
PERFORM create_table_purse_refunds(shard_suffix);
|
||||||
|
PERFORM add_constraints_to_purse_refunds_partition(shard_suffix);
|
||||||
|
|
||||||
PERFORM create_table_purse_merges(shard_suffix);
|
PERFORM create_table_purse_merges(shard_suffix);
|
||||||
PERFORM add_constraints_to_purse_merges_partition(shard_suffix);
|
PERFORM add_constraints_to_purse_merges_partition(shard_suffix);
|
||||||
|
|
||||||
@ -224,6 +227,10 @@ BEGIN
|
|||||||
'DROP TABLE IF EXISTS %I CASCADE'
|
'DROP TABLE IF EXISTS %I CASCADE'
|
||||||
,'purse_requests_' || shard_suffix
|
,'purse_requests_' || shard_suffix
|
||||||
);
|
);
|
||||||
|
EXECUTE FORMAT(
|
||||||
|
'DROP TABLE IF EXISTS %I CASCADE'
|
||||||
|
,'purse_refunds_' || shard_suffix
|
||||||
|
);
|
||||||
EXECUTE FORMAT(
|
EXECUTE FORMAT(
|
||||||
'DROP TABLE IF EXISTS %I CASCADE'
|
'DROP TABLE IF EXISTS %I CASCADE'
|
||||||
,'purse_merges_' || shard_suffix
|
,'purse_merges_' || shard_suffix
|
||||||
|
@ -646,6 +646,7 @@ audit_deposit_cb (void *cls,
|
|||||||
* @param h_contract_terms hash of the proposal data in
|
* @param h_contract_terms hash of the proposal data in
|
||||||
* the contract between merchant and customer
|
* the contract between merchant and customer
|
||||||
* @param rtransaction_id refund transaction ID chosen by the merchant
|
* @param rtransaction_id refund transaction ID chosen by the merchant
|
||||||
|
* @param full_refund the deposit
|
||||||
* @param amount_with_fee amount that was deposited including fee
|
* @param amount_with_fee amount that was deposited including fee
|
||||||
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
|
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
|
||||||
*/
|
*/
|
||||||
@ -658,6 +659,7 @@ audit_refund_cb (void *cls,
|
|||||||
const struct TALER_MerchantSignatureP *merchant_sig,
|
const struct TALER_MerchantSignatureP *merchant_sig,
|
||||||
const struct TALER_PrivateContractHashP *h_contract_terms,
|
const struct TALER_PrivateContractHashP *h_contract_terms,
|
||||||
uint64_t rtransaction_id,
|
uint64_t rtransaction_id,
|
||||||
|
bool full_refund,
|
||||||
const struct TALER_Amount *amount_with_fee)
|
const struct TALER_Amount *amount_with_fee)
|
||||||
{
|
{
|
||||||
(void) cls;
|
(void) cls;
|
||||||
@ -669,6 +671,7 @@ audit_refund_cb (void *cls,
|
|||||||
(void) h_contract_terms;
|
(void) h_contract_terms;
|
||||||
(void) rtransaction_id;
|
(void) rtransaction_id;
|
||||||
(void) amount_with_fee;
|
(void) amount_with_fee;
|
||||||
|
(void) full_refund;
|
||||||
auditor_row_cnt++;
|
auditor_row_cnt++;
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
|
1
src/include/.gitignore
vendored
Normal file
1
src/include/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
taler_signatures.h
|
@ -253,6 +253,11 @@ struct TALER_AUDITORDB_ProgressPointCoin
|
|||||||
*/
|
*/
|
||||||
uint64_t last_purse_deposits_serial_id;
|
uint64_t last_purse_deposits_serial_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serial ID of the last purse_refunds operation the auditor processed.
|
||||||
|
*/
|
||||||
|
uint64_t last_purse_refunds_serial_id;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -218,6 +218,7 @@ enum TALER_EXCHANGEDB_ReplicatedTable
|
|||||||
TALER_EXCHANGEDB_RT_EXTENSIONS,
|
TALER_EXCHANGEDB_RT_EXTENSIONS,
|
||||||
TALER_EXCHANGEDB_RT_EXTENSION_DETAILS,
|
TALER_EXCHANGEDB_RT_EXTENSION_DETAILS,
|
||||||
TALER_EXCHANGEDB_RT_PURSE_REQUESTS,
|
TALER_EXCHANGEDB_RT_PURSE_REQUESTS,
|
||||||
|
TALER_EXCHANGEDB_RT_PURSE_REFUNDS,
|
||||||
TALER_EXCHANGEDB_RT_PURSE_MERGES,
|
TALER_EXCHANGEDB_RT_PURSE_MERGES,
|
||||||
TALER_EXCHANGEDB_RT_PURSE_DEPOSITS,
|
TALER_EXCHANGEDB_RT_PURSE_DEPOSITS,
|
||||||
TALER_EXCHANGEDB_RT_ACCOUNT_MERGES,
|
TALER_EXCHANGEDB_RT_ACCOUNT_MERGES,
|
||||||
@ -495,6 +496,11 @@ struct TALER_EXCHANGEDB_TableData
|
|||||||
struct TALER_PurseContractSignatureP purse_sig;
|
struct TALER_PurseContractSignatureP purse_sig;
|
||||||
} purse_requests;
|
} purse_requests;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
struct TALER_PurseContractPublicKeyP purse_pub;
|
||||||
|
} purse_refunds;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint64_t partner_serial_id;
|
uint64_t partner_serial_id;
|
||||||
@ -1995,6 +2001,40 @@ typedef enum GNUNET_GenericReturnValue
|
|||||||
const struct TALER_DenominationPublicKey *denom_pub);
|
const struct TALER_DenominationPublicKey *denom_pub);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called with details about purse refunds that have been made, with
|
||||||
|
* the goal of auditing the purse refund's execution.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param rowid unique serial ID for the deposit in our DB
|
||||||
|
* @param purse_pub public key of the refunded purse
|
||||||
|
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
|
||||||
|
*/
|
||||||
|
typedef enum GNUNET_GenericReturnValue
|
||||||
|
(*TALER_EXCHANGEDB_PurseRefundCallback)(
|
||||||
|
void *cls,
|
||||||
|
uint64_t rowid,
|
||||||
|
const struct TALER_PurseContractPublicKeyP *purse_pub);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called with details about purse refunds that have been made, with
|
||||||
|
* the goal of auditing the purse refund's execution.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param amount_with_fee amount of the deposit into the purse
|
||||||
|
* @param coin_pub coin that is to be refunded the @a given amount_with_fee
|
||||||
|
* @param denom_pub denomination of @a coin_pub
|
||||||
|
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
|
||||||
|
*/
|
||||||
|
typedef enum GNUNET_GenericReturnValue
|
||||||
|
(*TALER_EXCHANGEDB_PurseRefundCoinCallback)(
|
||||||
|
void *cls,
|
||||||
|
const struct TALER_Amount *amount_with_fee,
|
||||||
|
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||||
|
const struct TALER_DenominationPublicKey *denom_pub);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function called with details about coins that were melted,
|
* Function called with details about coins that were melted,
|
||||||
* with the goal of auditing the refresh's execution.
|
* with the goal of auditing the refresh's execution.
|
||||||
@ -2198,6 +2238,7 @@ typedef void
|
|||||||
* @param merchant_sig signature of the merchant
|
* @param merchant_sig signature of the merchant
|
||||||
* @param h_contract_terms hash of the proposal data known to merchant and customer
|
* @param h_contract_terms hash of the proposal data known to merchant and customer
|
||||||
* @param rtransaction_id refund transaction ID chosen by the merchant
|
* @param rtransaction_id refund transaction ID chosen by the merchant
|
||||||
|
* @param full_refund true if the refunds total up to the entire value of the deposit
|
||||||
* @param amount_with_fee amount that was deposited including fee
|
* @param amount_with_fee amount that was deposited including fee
|
||||||
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
|
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
|
||||||
*/
|
*/
|
||||||
@ -2211,6 +2252,7 @@ typedef enum GNUNET_GenericReturnValue
|
|||||||
const struct TALER_MerchantSignatureP *merchant_sig,
|
const struct TALER_MerchantSignatureP *merchant_sig,
|
||||||
const struct TALER_PrivateContractHashP *h_contract_terms,
|
const struct TALER_PrivateContractHashP *h_contract_terms,
|
||||||
uint64_t rtransaction_id,
|
uint64_t rtransaction_id,
|
||||||
|
bool full_refund,
|
||||||
const struct TALER_Amount *amount_with_fee);
|
const struct TALER_Amount *amount_with_fee);
|
||||||
|
|
||||||
|
|
||||||
@ -4058,6 +4100,41 @@ struct TALER_EXCHANGEDB_Plugin
|
|||||||
void *cb_cls);
|
void *cb_cls);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select purse refunds above @a serial_id in monotonically increasing
|
||||||
|
* order.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param serial_id highest serial ID to exclude (select strictly larger)
|
||||||
|
* @param cb function to call on each result
|
||||||
|
* @param cb_cls closure for @a cb
|
||||||
|
* @return transaction status code
|
||||||
|
*/
|
||||||
|
enum GNUNET_DB_QueryStatus
|
||||||
|
(*select_purse_refunds_above_serial_id)(
|
||||||
|
void *cls,
|
||||||
|
uint64_t serial_id,
|
||||||
|
TALER_EXCHANGEDB_PurseRefundCallback cb,
|
||||||
|
void *cb_cls);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select coins deposited into a purse.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param purse_pub public key of the purse
|
||||||
|
* @param cb function to call on each result
|
||||||
|
* @param cb_cls closure for @a cb
|
||||||
|
* @return transaction status code
|
||||||
|
*/
|
||||||
|
enum GNUNET_DB_QueryStatus
|
||||||
|
(*select_purse_deposits_by_purse)(
|
||||||
|
void *cls,
|
||||||
|
const struct TALER_PurseContractPublicKeyP *purse_pub,
|
||||||
|
TALER_EXCHANGEDB_PurseRefundCoinCallback cb,
|
||||||
|
void *cb_cls);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select refresh sessions above @a serial_id in monotonically increasing
|
* Select refresh sessions above @a serial_id in monotonically increasing
|
||||||
* order.
|
* order.
|
||||||
|
Loading…
Reference in New Issue
Block a user