towards changing timestamp in deposit confirmation (tests failing)

This commit is contained in:
Christian Grothoff 2020-05-07 20:22:02 +02:00
parent 0dfe7c23cb
commit 7217b8d065
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
25 changed files with 412 additions and 211 deletions

View File

@ -155,7 +155,7 @@ verify_and_execute_deposit_confirmation (
.purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS)), .purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS)),
.h_contract_terms = dc->h_contract_terms, .h_contract_terms = dc->h_contract_terms,
.h_wire = dc->h_wire, .h_wire = dc->h_wire,
.timestamp = GNUNET_TIME_absolute_hton (dc->timestamp), .exchange_timestamp = GNUNET_TIME_absolute_hton (dc->exchange_timestamp),
.refund_deadline = GNUNET_TIME_absolute_hton (dc->refund_deadline), .refund_deadline = GNUNET_TIME_absolute_hton (dc->refund_deadline),
.coin_pub = dc->coin_pub, .coin_pub = dc->coin_pub,
.merchant = dc->merchant .merchant = dc->merchant
@ -224,7 +224,8 @@ TAH_DEPOSIT_CONFIRMATION_handler (struct TAH_RequestHandler *rh,
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("h_contract_terms", &dc.h_contract_terms), GNUNET_JSON_spec_fixed_auto ("h_contract_terms", &dc.h_contract_terms),
GNUNET_JSON_spec_fixed_auto ("h_wire", &dc.h_wire), GNUNET_JSON_spec_fixed_auto ("h_wire", &dc.h_wire),
GNUNET_JSON_spec_absolute_time ("timestamp", &dc.timestamp), GNUNET_JSON_spec_absolute_time ("exchange_timestamp",
&dc.exchange_timestamp),
GNUNET_JSON_spec_absolute_time ("refund_deadline", &dc.refund_deadline), GNUNET_JSON_spec_absolute_time ("refund_deadline", &dc.refund_deadline),
TALER_JSON_spec_amount ("amount_without_fee", &dc.amount_without_fee), TALER_JSON_spec_amount ("amount_without_fee", &dc.amount_without_fee),
GNUNET_JSON_spec_fixed_auto ("coin_pub", &dc.coin_pub), GNUNET_JSON_spec_fixed_auto ("coin_pub", &dc.coin_pub),

View File

@ -1535,7 +1535,8 @@ refresh_session_cb (void *cls,
* *
* @param cls closure * @param cls closure
* @param rowid unique serial ID for the deposit in our DB * @param rowid unique serial ID for the deposit in our DB
* @param timestamp when did the deposit happen * @param exchange_timestamp when did the exchange get the deposit
* @param wallet_timestamp when did the contract signing happen
* @param merchant_pub public key of the merchant * @param merchant_pub public key of the merchant
* @param denom_pub denomination public key of @a coin_pub * @param denom_pub denomination public key of @a coin_pub
* @param coin_pub public key of the coin * @param coin_pub public key of the coin
@ -1553,7 +1554,8 @@ refresh_session_cb (void *cls,
static int static int
deposit_cb (void *cls, deposit_cb (void *cls,
uint64_t rowid, uint64_t rowid,
struct GNUNET_TIME_Absolute timestamp, struct GNUNET_TIME_Absolute exchange_timestamp,
struct GNUNET_TIME_Absolute wallet_timestamp,
const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_DenominationPublicKey *denom_pub,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
@ -1611,7 +1613,7 @@ deposit_cb (void *cls,
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT), .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT),
.purpose.size = htonl (sizeof (dr)), .purpose.size = htonl (sizeof (dr)),
.h_contract_terms = *h_contract_terms, .h_contract_terms = *h_contract_terms,
.timestamp = GNUNET_TIME_absolute_hton (timestamp), .wallet_timestamp = GNUNET_TIME_absolute_hton (wallet_timestamp),
.refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline), .refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline),
.deposit_fee = issue->fee_deposit, .deposit_fee = issue->fee_deposit,
.merchant = *merchant_pub, .merchant = *merchant_pub,

View File

@ -114,11 +114,15 @@ test_dc (void *cls,
.h_wire = dc->h_wire, .h_wire = dc->h_wire,
.refund_deadline = dc->refund_deadline .refund_deadline = dc->refund_deadline
}; };
struct GNUNET_TIME_Absolute exchange_timestamp;
struct TALER_Amount deposit_fee;
qs = TALER_ARL_edb->have_deposit (TALER_ARL_edb->cls, qs = TALER_ARL_edb->have_deposit (TALER_ARL_edb->cls,
TALER_ARL_esession, TALER_ARL_esession,
&dep, &dep,
GNUNET_NO /* do not check refund deadline */); GNUNET_NO /* do not check refund deadline */,
&deposit_fee,
&exchange_timestamp);
if (qs > 0) if (qs > 0)
{ {
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@ -137,7 +141,8 @@ test_dc (void *cls,
TALER_ARL_report (report_deposit_confirmation_inconsistencies, TALER_ARL_report (report_deposit_confirmation_inconsistencies,
json_pack ("{s:o, s:o, s:I, s:o}", json_pack ("{s:o, s:o, s:I, s:o}",
"timestamp", "timestamp",
TALER_ARL_json_from_time_abs (dc->timestamp), TALER_ARL_json_from_time_abs (
dc->exchange_timestamp),
"amount", "amount",
TALER_JSON_from_amount (&dc->amount_without_fee), TALER_JSON_from_amount (&dc->amount_without_fee),
"rowid", "rowid",

View File

@ -251,7 +251,7 @@ CREATE TABLE IF NOT EXISTS deposit_confirmations
,serial_id BIGSERIAL UNIQUE ,serial_id BIGSERIAL UNIQUE
,h_contract_terms BYTEA CHECK (LENGTH(h_contract_terms)=64) ,h_contract_terms BYTEA CHECK (LENGTH(h_contract_terms)=64)
,h_wire BYTEA CHECK (LENGTH(h_wire)=64) ,h_wire BYTEA CHECK (LENGTH(h_wire)=64)
,timestamp INT8 NOT NULL ,exchange_timestamp INT8 NOT NULL
,refund_deadline INT8 NOT NULL ,refund_deadline INT8 NOT NULL
,amount_without_fee_val INT8 NOT NULL ,amount_without_fee_val INT8 NOT NULL
,amount_without_fee_frac INT4 NOT NULL ,amount_without_fee_frac INT4 NOT NULL

View File

@ -269,7 +269,7 @@ postgres_get_session (void *cls)
"(master_pub" "(master_pub"
",h_contract_terms" ",h_contract_terms"
",h_wire" ",h_wire"
",timestamp" ",exchange_timestamp"
",refund_deadline" ",refund_deadline"
",amount_without_fee_val" ",amount_without_fee_val"
",amount_without_fee_frac" ",amount_without_fee_frac"
@ -286,7 +286,7 @@ postgres_get_session (void *cls)
" serial_id" " serial_id"
",h_contract_terms" ",h_contract_terms"
",h_wire" ",h_wire"
",timestamp" ",exchange_timestamp"
",refund_deadline" ",refund_deadline"
",amount_without_fee_val" ",amount_without_fee_val"
",amount_without_fee_frac" ",amount_without_fee_frac"
@ -1126,7 +1126,7 @@ postgres_insert_deposit_confirmation (
GNUNET_PQ_query_param_auto_from_type (&dc->master_public_key), GNUNET_PQ_query_param_auto_from_type (&dc->master_public_key),
GNUNET_PQ_query_param_auto_from_type (&dc->h_contract_terms), GNUNET_PQ_query_param_auto_from_type (&dc->h_contract_terms),
GNUNET_PQ_query_param_auto_from_type (&dc->h_wire), GNUNET_PQ_query_param_auto_from_type (&dc->h_wire),
TALER_PQ_query_param_absolute_time (&dc->timestamp), TALER_PQ_query_param_absolute_time (&dc->exchange_timestamp),
TALER_PQ_query_param_absolute_time (&dc->refund_deadline), TALER_PQ_query_param_absolute_time (&dc->refund_deadline),
TALER_PQ_query_param_amount (&dc->amount_without_fee), TALER_PQ_query_param_amount (&dc->amount_without_fee),
GNUNET_PQ_query_param_auto_from_type (&dc->coin_pub), GNUNET_PQ_query_param_auto_from_type (&dc->coin_pub),
@ -1207,8 +1207,8 @@ deposit_confirmation_cb (void *cls,
&dc.h_contract_terms), &dc.h_contract_terms),
GNUNET_PQ_result_spec_auto_from_type ("h_wire", GNUNET_PQ_result_spec_auto_from_type ("h_wire",
&dc.h_wire), &dc.h_wire),
GNUNET_PQ_result_spec_absolute_time ("timestamp", GNUNET_PQ_result_spec_absolute_time ("exchange_timestamp",
&dc.timestamp), &dc.exchange_timestamp),
GNUNET_PQ_result_spec_absolute_time ("refund_deadline", GNUNET_PQ_result_spec_absolute_time ("refund_deadline",
&dc.refund_deadline), &dc.refund_deadline),
TALER_PQ_RESULT_SPEC_AMOUNT ("amount_without_fee", TALER_PQ_RESULT_SPEC_AMOUNT ("amount_without_fee",

View File

@ -330,6 +330,8 @@ refund_by_coin_cb (void *cls,
* *
* @param cls a `struct AggregationUnit` * @param cls a `struct AggregationUnit`
* @param row_id identifies database entry * @param row_id identifies database entry
* @param exchange_timestamp when did the deposit happen
* @param wallet_timestamp when did the contract happen
* @param merchant_pub public key of the merchant * @param merchant_pub public key of the merchant
* @param coin_pub public key of the coin * @param coin_pub public key of the coin
* @param amount_with_fee amount that was deposited including fee * @param amount_with_fee amount that was deposited including fee
@ -343,6 +345,8 @@ refund_by_coin_cb (void *cls,
static enum GNUNET_DB_QueryStatus static enum GNUNET_DB_QueryStatus
deposit_cb (void *cls, deposit_cb (void *cls,
uint64_t row_id, uint64_t row_id,
struct GNUNET_TIME_Absolute exchange_timestamp,
struct GNUNET_TIME_Absolute wallet_timestamp,
const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_Amount *amount_with_fee, const struct TALER_Amount *amount_with_fee,
@ -358,6 +362,8 @@ deposit_cb (void *cls,
/* NOTE: potential optimization: use custom SQL API to not /* NOTE: potential optimization: use custom SQL API to not
fetch this one: */ fetch this one: */
(void) wire_deadline; /* already checked by SQL query */ (void) wire_deadline; /* already checked by SQL query */
(void) exchange_timestamp;
(void) wallet_timestamp;
au->merchant_pub = *merchant_pub; au->merchant_pub = *merchant_pub;
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Aggregator processing payment %s with amount %s\n", "Aggregator processing payment %s with amount %s\n",
@ -501,6 +507,8 @@ deposit_cb (void *cls,
* *
* @param cls a `struct AggregationUnit` * @param cls a `struct AggregationUnit`
* @param row_id identifies database entry * @param row_id identifies database entry
* @param exchange_timestamp when did the exchange receive the deposit
* @param wallet_timestamp when did the wallet sign the contract
* @param merchant_pub public key of the merchant * @param merchant_pub public key of the merchant
* @param coin_pub public key of the coin * @param coin_pub public key of the coin
* @param amount_with_fee amount that was deposited including fee * @param amount_with_fee amount that was deposited including fee
@ -514,6 +522,8 @@ deposit_cb (void *cls,
static enum GNUNET_DB_QueryStatus static enum GNUNET_DB_QueryStatus
aggregate_cb (void *cls, aggregate_cb (void *cls,
uint64_t row_id, uint64_t row_id,
struct GNUNET_TIME_Absolute exchange_timestamp,
struct GNUNET_TIME_Absolute wallet_timestamp,
const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_Amount *amount_with_fee, const struct TALER_Amount *amount_with_fee,
@ -529,6 +539,8 @@ aggregate_cb (void *cls,
/* NOTE: potential optimization: use custom SQL API to not /* NOTE: potential optimization: use custom SQL API to not
fetch these: */ fetch these: */
(void) wire_deadline; /* checked by SQL */ (void) wire_deadline; /* checked by SQL */
(void) exchange_timestamp;
(void) wallet_timestamp;
(void) wire; /* must match */ (void) wire; /* must match */
GNUNET_break (0 == GNUNET_memcmp (&au->merchant_pub, GNUNET_break (0 == GNUNET_memcmp (&au->merchant_pub,
merchant_pub)); merchant_pub));

View File

@ -47,7 +47,7 @@
* @param coin_pub public key of the coin * @param coin_pub public key of the coin
* @param h_wire hash of wire details * @param h_wire hash of wire details
* @param h_contract_terms hash of contract details * @param h_contract_terms hash of contract details
* @param timestamp client's timestamp * @param exchange_timestamp exchange's timestamp
* @param refund_deadline until when this deposit be refunded * @param refund_deadline until when this deposit be refunded
* @param merchant merchant public key * @param merchant merchant public key
* @param amount_without_fee fraction of coin value to deposit, without the fee * @param amount_without_fee fraction of coin value to deposit, without the fee
@ -58,7 +58,7 @@ reply_deposit_success (struct MHD_Connection *connection,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct GNUNET_HashCode *h_wire, const struct GNUNET_HashCode *h_wire,
const struct GNUNET_HashCode *h_contract_terms, const struct GNUNET_HashCode *h_contract_terms,
struct GNUNET_TIME_Absolute timestamp, struct GNUNET_TIME_Absolute exchange_timestamp,
struct GNUNET_TIME_Absolute refund_deadline, struct GNUNET_TIME_Absolute refund_deadline,
const struct TALER_MerchantPublicKeyP *merchant, const struct TALER_MerchantPublicKeyP *merchant,
const struct TALER_Amount *amount_without_fee) const struct TALER_Amount *amount_without_fee)
@ -70,7 +70,7 @@ reply_deposit_success (struct MHD_Connection *connection,
.purpose.size = htonl (sizeof (dc)), .purpose.size = htonl (sizeof (dc)),
.h_contract_terms = *h_contract_terms, .h_contract_terms = *h_contract_terms,
.h_wire = *h_wire, .h_wire = *h_wire,
.timestamp = GNUNET_TIME_absolute_hton (timestamp), .exchange_timestamp = GNUNET_TIME_absolute_hton (exchange_timestamp),
.refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline), .refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline),
.coin_pub = *coin_pub, .coin_pub = *coin_pub,
.merchant = *merchant .merchant = *merchant
@ -88,9 +88,12 @@ reply_deposit_success (struct MHD_Connection *connection,
TALER_EC_EXCHANGE_BAD_CONFIGURATION, TALER_EC_EXCHANGE_BAD_CONFIGURATION,
"no keys"); "no keys");
} }
return TALER_MHD_reply_json_pack (connection, return TALER_MHD_reply_json_pack (
connection,
MHD_HTTP_OK, MHD_HTTP_OK,
"{s:o, s:o}", "{s:o, s:o, s:o}",
"exchange_timestamp",
GNUNET_JSON_from_time_abs (exchange_timestamp),
"exchange_sig", "exchange_sig",
GNUNET_JSON_from_data_auto (&sig), GNUNET_JSON_from_data_auto (&sig),
"exchange_pub", "exchange_pub",
@ -108,6 +111,11 @@ struct DepositContext
*/ */
const struct TALER_EXCHANGEDB_Deposit *deposit; const struct TALER_EXCHANGEDB_Deposit *deposit;
/**
* Our timestamp (when we received the request).
*/
struct GNUNET_TIME_Absolute exchange_timestamp;
/** /**
* Value of the coin. * Value of the coin.
*/ */
@ -116,6 +124,74 @@ struct DepositContext
}; };
/**
* Check if /deposit is already in the database. IF it returns a non-error
* code, the transaction logic MUST NOT queue a MHD response. IF it returns
* an hard error, the transaction logic MUST queue a MHD response and set @a
* mhd_ret. We do return a "hard" error also if we found the deposit in the
* database and generated a regular response.
*
* @param cls a `struct DepositContext`
* @param connection MHD request context
* @param session database session and transaction to use
* @param[out] mhd_ret set to MHD status on error
* @return transaction status
*/
static enum GNUNET_DB_QueryStatus
deposit_precheck (void *cls,
struct MHD_Connection *connection,
struct TALER_EXCHANGEDB_Session *session,
MHD_RESULT *mhd_ret)
{
struct DepositContext *dc = cls;
const struct TALER_EXCHANGEDB_Deposit *deposit = dc->deposit;
struct TALER_Amount deposit_fee;
enum GNUNET_DB_QueryStatus qs;
qs = TEH_plugin->have_deposit (TEH_plugin->cls,
session,
deposit,
GNUNET_YES /* check refund deadline */,
&deposit_fee,
&dc->exchange_timestamp);
if (qs < 0)
{
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
*mhd_ret = TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_DEPOSIT_HISTORY_DB_ERROR,
"Could not check for existing identical deposit");
return GNUNET_DB_STATUS_HARD_ERROR;
}
return qs;
}
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
{
struct TALER_Amount amount_without_fee;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"/deposit replay, accepting again!\n");
GNUNET_assert (0 <=
TALER_amount_subtract (&amount_without_fee,
&deposit->amount_with_fee,
&deposit_fee));
*mhd_ret = reply_deposit_success (connection,
&deposit->coin.coin_pub,
&deposit->h_wire,
&deposit->h_contract_terms,
dc->exchange_timestamp,
deposit->refund_deadline,
&deposit->merchant_pub,
&amount_without_fee);
/* Treat as 'hard' DB error as we want to rollback and
never try again. */
return GNUNET_DB_STATUS_HARD_ERROR;
}
return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
}
/** /**
* Execute database transaction for /deposit. Runs the transaction * Execute database transaction for /deposit. Runs the transaction
* logic; IF it returns a non-error code, the transaction logic MUST * logic; IF it returns a non-error code, the transaction logic MUST
@ -141,44 +217,15 @@ deposit_transaction (void *cls,
struct TALER_Amount spent; struct TALER_Amount spent;
enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs;
qs = TEH_plugin->have_deposit (TEH_plugin->cls, /* Theoretically, someone other threat may have received
and committed the deposit in the meantime. Check now
that we are in the transaction scope. */
qs = deposit_precheck (cls,
connection,
session, session,
deposit, mhd_ret);
GNUNET_YES /* check refund deadline */);
if (qs < 0) if (qs < 0)
{
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
*mhd_ret = TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_DEPOSIT_HISTORY_DB_ERROR,
"Could not check for existing identical deposit");
return GNUNET_DB_STATUS_HARD_ERROR;
}
return qs; return qs;
}
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
{
struct TALER_Amount amount_without_fee;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"/deposit replay, accepting again!\n");
GNUNET_assert (0 <=
TALER_amount_subtract (&amount_without_fee,
&deposit->amount_with_fee,
&deposit->deposit_fee));
*mhd_ret = reply_deposit_success (connection,
&deposit->coin.coin_pub,
&deposit->h_wire,
&deposit->h_contract_terms,
deposit->timestamp,
deposit->refund_deadline,
&deposit->merchant_pub,
&amount_without_fee);
/* Treat as 'hard' DB error as we want to rollback and
never try again. */
return GNUNET_DB_STATUS_HARD_ERROR;
}
/* Start with fee for THIS transaction */ /* Start with fee for THIS transaction */
spent = deposit->amount_with_fee; spent = deposit->amount_with_fee;
@ -238,6 +285,7 @@ deposit_transaction (void *cls,
} }
qs = TEH_plugin->insert_deposit (TEH_plugin->cls, qs = TEH_plugin->insert_deposit (TEH_plugin->cls,
session, session,
dc->exchange_timestamp,
deposit); deposit);
if (GNUNET_DB_STATUS_HARD_ERROR == qs) if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{ {
@ -251,45 +299,6 @@ deposit_transaction (void *cls,
} }
/**
* Check that @a ts is reasonably close to our own RTC.
*
* @param ts timestamp to check
* @return #GNUNET_OK if @a ts is reasonable
*/
static int
check_timestamp_current (struct GNUNET_TIME_Absolute ts)
{
struct GNUNET_TIME_Relative r;
struct GNUNET_TIME_Relative tolerance;
/* Let's be VERY generous (after all, this is basically about
which year the deposit counts for in terms of tax purposes) */
tolerance = GNUNET_TIME_UNIT_MONTHS;
r = GNUNET_TIME_absolute_get_duration (ts);
if (r.rel_value_us > tolerance.rel_value_us)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Deposit timestamp too old: %llu vs %llu > %llu\n",
(unsigned long long) ts.abs_value_us,
(unsigned long long) GNUNET_TIME_absolute_get ().abs_value_us,
(unsigned long long) tolerance.rel_value_us);
return GNUNET_SYSERR;
}
r = GNUNET_TIME_absolute_get_remaining (ts);
if (r.rel_value_us > tolerance.rel_value_us)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Deposit timestamp too new: %llu vs %llu < - %llu\n",
(unsigned long long) ts.abs_value_us,
(unsigned long long) GNUNET_TIME_absolute_get ().abs_value_us,
(unsigned long long) tolerance.rel_value_us);
return GNUNET_SYSERR;
}
return GNUNET_OK;
}
/** /**
* Handle a "/coins/$COIN_PUB/deposit" request. Parses the JSON, and, if * Handle a "/coins/$COIN_PUB/deposit" request. Parses the JSON, and, if
* successful, passes the JSON data to #deposit_transaction() to * successful, passes the JSON data to #deposit_transaction() to
@ -367,17 +376,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
TALER_EC_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE, TALER_EC_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE,
"refund_deadline"); "refund_deadline");
} }
if (GNUNET_OK !=
check_timestamp_current (deposit.timestamp))
{
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_DEPOSIT_INVALID_TIMESTAMP,
"timestamp");
}
if (GNUNET_OK != if (GNUNET_OK !=
TALER_JSON_merchant_wire_signature_hash (wire, TALER_JSON_merchant_wire_signature_hash (wire,
&my_h_wire)) &my_h_wire))
@ -401,6 +399,26 @@ TEH_handler_deposit (struct MHD_Connection *connection,
"h_wire"); "h_wire");
} }
/* Check for idempotency: did we get this request before? */
dc.deposit = &deposit;
{
MHD_RESULT mhd_ret;
if (GNUNET_OK !=
TEH_DB_run_transaction (connection,
"precheck deposit",
&mhd_ret,
&deposit_precheck,
&dc))
{
GNUNET_JSON_parse_free (spec);
return mhd_ret;
}
}
/* new deposit */
dc.exchange_timestamp = GNUNET_TIME_absolute_get ();
(void) GNUNET_TIME_round_abs (&dc.exchange_timestamp);
/* check denomination exists and is valid */ /* check denomination exists and is valid */
{ {
struct TEH_KS_StateHandle *key_state; struct TEH_KS_StateHandle *key_state;
@ -408,7 +426,7 @@ TEH_handler_deposit (struct MHD_Connection *connection,
enum TALER_ErrorCode ec; enum TALER_ErrorCode ec;
unsigned int hc; unsigned int hc;
key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ()); key_state = TEH_KS_acquire (dc.exchange_timestamp);
if (NULL == key_state) if (NULL == key_state)
{ {
TALER_LOG_ERROR ("Lacking keys to operate\n"); TALER_LOG_ERROR ("Lacking keys to operate\n");
@ -502,7 +520,7 @@ TEH_handler_deposit (struct MHD_Connection *connection,
.purpose.size = htonl (sizeof (dr)), .purpose.size = htonl (sizeof (dr)),
.h_contract_terms = deposit.h_contract_terms, .h_contract_terms = deposit.h_contract_terms,
.h_wire = deposit.h_wire, .h_wire = deposit.h_wire,
.timestamp = GNUNET_TIME_absolute_hton (deposit.timestamp), .wallet_timestamp = GNUNET_TIME_absolute_hton (deposit.timestamp),
.refund_deadline = GNUNET_TIME_absolute_hton (deposit.refund_deadline), .refund_deadline = GNUNET_TIME_absolute_hton (deposit.refund_deadline),
.merchant = deposit.merchant_pub, .merchant = deposit.merchant_pub,
.coin_pub = deposit.coin.coin_pub .coin_pub = deposit.coin.coin_pub
@ -528,7 +546,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
} }
/* execute transaction */ /* execute transaction */
dc.deposit = &deposit;
{ {
MHD_RESULT mhd_ret; MHD_RESULT mhd_ret;
@ -557,7 +574,7 @@ TEH_handler_deposit (struct MHD_Connection *connection,
&deposit.coin.coin_pub, &deposit.coin.coin_pub,
&deposit.h_wire, &deposit.h_wire,
&deposit.h_contract_terms, &deposit.h_contract_terms,
deposit.timestamp, dc.exchange_timestamp,
deposit.refund_deadline, deposit.refund_deadline,
&deposit.merchant_pub, &deposit.merchant_pub,
&amount_without_fee); &amount_without_fee);

View File

@ -66,7 +66,7 @@ TEH_RESPONSE_compile_transaction_history (
.purpose.size = htonl (sizeof (dr)), .purpose.size = htonl (sizeof (dr)),
.h_contract_terms = deposit->h_contract_terms, .h_contract_terms = deposit->h_contract_terms,
.h_wire = deposit->h_wire, .h_wire = deposit->h_wire,
.timestamp = GNUNET_TIME_absolute_hton (deposit->timestamp), .wallet_timestamp = GNUNET_TIME_absolute_hton (deposit->timestamp),
.refund_deadline = GNUNET_TIME_absolute_hton ( .refund_deadline = GNUNET_TIME_absolute_hton (
deposit->refund_deadline), deposit->refund_deadline),
.merchant = deposit->merchant_pub, .merchant = deposit->merchant_pub,

View File

@ -254,7 +254,8 @@ CREATE TABLE IF NOT EXISTS deposits
,coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub) ON DELETE CASCADE ,coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub) ON DELETE CASCADE
,amount_with_fee_val INT8 NOT NULL ,amount_with_fee_val INT8 NOT NULL
,amount_with_fee_frac INT4 NOT NULL ,amount_with_fee_frac INT4 NOT NULL
,timestamp INT8 NOT NULL ,wallet_timestamp INT8 NOT NULL
,exchange_timestamp INT8 NOT NULL
,refund_deadline INT8 NOT NULL ,refund_deadline INT8 NOT NULL
,wire_deadline INT8 NOT NULL ,wire_deadline INT8 NOT NULL
,merchant_pub BYTEA NOT NULL CHECK (LENGTH(merchant_pub)=32) ,merchant_pub BYTEA NOT NULL CHECK (LENGTH(merchant_pub)=32)

View File

@ -796,7 +796,7 @@ postgres_get_session (void *cls)
"(coin_pub" "(coin_pub"
",amount_with_fee_val" ",amount_with_fee_val"
",amount_with_fee_frac" ",amount_with_fee_frac"
",timestamp" ",wallet_timestamp"
",refund_deadline" ",refund_deadline"
",wire_deadline" ",wire_deadline"
",merchant_pub" ",merchant_pub"
@ -804,22 +804,28 @@ postgres_get_session (void *cls)
",h_wire" ",h_wire"
",coin_sig" ",coin_sig"
",wire" ",wire"
",exchange_timestamp"
") VALUES " ") VALUES "
"($1, $2, $3, $4, $5, $6, $7, $8, $9, $10," "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10,"
" $11);", " $11, $12);",
11), 12),
/* Fetch an existing deposit request, used to ensure idempotency /* Fetch an existing deposit request, used to ensure idempotency
during /deposit processing. Used in #postgres_have_deposit(). */ during /deposit processing. Used in #postgres_have_deposit(). */
GNUNET_PQ_make_prepare ("get_deposit", GNUNET_PQ_make_prepare ("get_deposit",
"SELECT" "SELECT"
" amount_with_fee_val" " amount_with_fee_val"
",amount_with_fee_frac" ",amount_with_fee_frac"
",timestamp" ",denominations.fee_deposit_val"
",denominations.fee_deposit_frac"
",wallet_timestamp"
",exchange_timestamp"
",refund_deadline" ",refund_deadline"
",wire_deadline" ",wire_deadline"
",h_contract_terms" ",h_contract_terms"
",h_wire" ",h_wire"
" FROM deposits" " FROM deposits"
" JOIN known_coins USING (coin_pub)"
" JOIN denominations USING (denom_pub_hash)"
" WHERE ((coin_pub=$1)" " WHERE ((coin_pub=$1)"
" AND (merchant_pub=$3)" " AND (merchant_pub=$3)"
" AND (h_contract_terms=$2))" " AND (h_contract_terms=$2))"
@ -830,7 +836,8 @@ postgres_get_session (void *cls)
"SELECT" "SELECT"
" amount_with_fee_val" " amount_with_fee_val"
",amount_with_fee_frac" ",amount_with_fee_frac"
",timestamp" ",wallet_timestamp"
",exchange_timestamp"
",merchant_pub" ",merchant_pub"
",denom.denom_pub" ",denom.denom_pub"
",coin_pub" ",coin_pub"
@ -881,6 +888,8 @@ postgres_get_session (void *cls)
",wire" ",wire"
",merchant_pub" ",merchant_pub"
",coin_pub" ",coin_pub"
",exchange_timestamp"
",wallet_timestamp"
" FROM deposits" " FROM deposits"
" JOIN known_coins USING (coin_pub)" " JOIN known_coins USING (coin_pub)"
" JOIN denominations denom USING (denom_pub_hash)" " JOIN denominations denom USING (denom_pub_hash)"
@ -900,6 +909,8 @@ postgres_get_session (void *cls)
",denom.fee_deposit_val" ",denom.fee_deposit_val"
",denom.fee_deposit_frac" ",denom.fee_deposit_frac"
",wire_deadline" ",wire_deadline"
",exchange_timestamp"
",wallet_timestamp"
",h_contract_terms" ",h_contract_terms"
",coin_pub" ",coin_pub"
" FROM deposits" " FROM deposits"
@ -945,7 +956,7 @@ postgres_get_session (void *cls)
",amount_with_fee_frac" ",amount_with_fee_frac"
",denom.fee_deposit_val" ",denom.fee_deposit_val"
",denom.fee_deposit_frac" ",denom.fee_deposit_frac"
",timestamp" ",wallet_timestamp"
",refund_deadline" ",refund_deadline"
",wire_deadline" ",wire_deadline"
",merchant_pub" ",merchant_pub"
@ -2571,6 +2582,8 @@ postgres_get_reserve_history (void *cls,
* @param session database connection * @param session database connection
* @param deposit deposit to search for * @param deposit deposit to search for
* @param check_extras whether to check extra fields match or not * @param check_extras whether to check extra fields match or not
* @param[out] deposit_fee set to the deposit fee the exchange charged
* @param[out] exchange_timestamp set to the time when the exchange received the deposit
* @return 1 if we know this operation, * @return 1 if we know this operation,
* 0 if this exact deposit is unknown to us, * 0 if this exact deposit is unknown to us,
* otherwise transaction error status * otherwise transaction error status
@ -2579,7 +2592,9 @@ static enum GNUNET_DB_QueryStatus
postgres_have_deposit (void *cls, postgres_have_deposit (void *cls,
struct TALER_EXCHANGEDB_Session *session, struct TALER_EXCHANGEDB_Session *session,
const struct TALER_EXCHANGEDB_Deposit *deposit, const struct TALER_EXCHANGEDB_Deposit *deposit,
int check_extras) int check_extras,
struct TALER_Amount *deposit_fee,
struct GNUNET_TIME_Absolute *exchange_timestamp)
{ {
struct PostgresClosure *pg = cls; struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = { struct GNUNET_PQ_QueryParam params[] = {
@ -2592,12 +2607,16 @@ postgres_have_deposit (void *cls,
struct GNUNET_PQ_ResultSpec rs[] = { struct GNUNET_PQ_ResultSpec rs[] = {
TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
&deposit2.amount_with_fee), &deposit2.amount_with_fee),
TALER_PQ_result_spec_absolute_time ("timestamp", TALER_PQ_result_spec_absolute_time ("wallet_timestamp",
&deposit2.timestamp), &deposit2.timestamp),
TALER_PQ_result_spec_absolute_time ("exchange_timestamp",
exchange_timestamp),
TALER_PQ_result_spec_absolute_time ("refund_deadline", TALER_PQ_result_spec_absolute_time ("refund_deadline",
&deposit2.refund_deadline), &deposit2.refund_deadline),
TALER_PQ_result_spec_absolute_time ("wire_deadline", TALER_PQ_result_spec_absolute_time ("wire_deadline",
&deposit2.wire_deadline), &deposit2.wire_deadline),
TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit",
deposit_fee),
GNUNET_PQ_result_spec_auto_from_type ("h_wire", GNUNET_PQ_result_spec_auto_from_type ("h_wire",
&deposit2.h_wire), &deposit2.h_wire),
GNUNET_PQ_result_spec_end GNUNET_PQ_result_spec_end
@ -2776,6 +2795,8 @@ postgres_get_ready_deposit (void *cls,
struct TALER_Amount amount_with_fee; struct TALER_Amount amount_with_fee;
struct TALER_Amount deposit_fee; struct TALER_Amount deposit_fee;
struct GNUNET_TIME_Absolute wire_deadline; struct GNUNET_TIME_Absolute wire_deadline;
struct GNUNET_TIME_Absolute wallet_timestamp;
struct GNUNET_TIME_Absolute exchange_timestamp;
struct GNUNET_HashCode h_contract_terms; struct GNUNET_HashCode h_contract_terms;
struct TALER_MerchantPublicKeyP merchant_pub; struct TALER_MerchantPublicKeyP merchant_pub;
struct TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendPublicKeyP coin_pub;
@ -2788,6 +2809,10 @@ postgres_get_ready_deposit (void *cls,
&amount_with_fee), &amount_with_fee),
TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit", TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit",
&deposit_fee), &deposit_fee),
TALER_PQ_result_spec_absolute_time ("exchange_timestamp",
&exchange_timestamp),
TALER_PQ_result_spec_absolute_time ("wallet_timestamp",
&wallet_timestamp),
TALER_PQ_result_spec_absolute_time ("wire_deadline", TALER_PQ_result_spec_absolute_time ("wire_deadline",
&wire_deadline), &wire_deadline),
GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
@ -2817,6 +2842,8 @@ postgres_get_ready_deposit (void *cls,
qs = deposit_cb (deposit_cb_cls, qs = deposit_cb (deposit_cb_cls,
serial_id, serial_id,
exchange_timestamp,
wallet_timestamp,
&merchant_pub, &merchant_pub,
&coin_pub, &coin_pub,
&amount_with_fee, &amount_with_fee,
@ -2898,6 +2925,8 @@ match_deposit_cb (void *cls,
{ {
struct TALER_Amount amount_with_fee; struct TALER_Amount amount_with_fee;
struct TALER_Amount deposit_fee; struct TALER_Amount deposit_fee;
struct GNUNET_TIME_Absolute exchange_timestamp;
struct GNUNET_TIME_Absolute wallet_timestamp;
struct GNUNET_TIME_Absolute wire_deadline; struct GNUNET_TIME_Absolute wire_deadline;
struct GNUNET_HashCode h_contract_terms; struct GNUNET_HashCode h_contract_terms;
struct TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendPublicKeyP coin_pub;
@ -2912,6 +2941,10 @@ match_deposit_cb (void *cls,
&deposit_fee), &deposit_fee),
TALER_PQ_result_spec_absolute_time ("wire_deadline", TALER_PQ_result_spec_absolute_time ("wire_deadline",
&wire_deadline), &wire_deadline),
TALER_PQ_result_spec_absolute_time ("exchange_timestamp",
&exchange_timestamp),
TALER_PQ_result_spec_absolute_time ("wallet_timestamp",
&wallet_timestamp),
GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
&h_contract_terms), &h_contract_terms),
GNUNET_PQ_result_spec_auto_from_type ("coin_pub", GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
@ -2930,6 +2963,8 @@ match_deposit_cb (void *cls,
} }
qs = mdc->deposit_cb (mdc->deposit_cb_cls, qs = mdc->deposit_cb (mdc->deposit_cb_cls,
serial_id, serial_id,
exchange_timestamp,
wallet_timestamp,
mdc->merchant_pub, mdc->merchant_pub,
&coin_pub, &coin_pub,
&amount_with_fee, &amount_with_fee,
@ -3210,12 +3245,14 @@ postgres_ensure_coin_known (void *cls,
* *
* @param cls the `struct PostgresClosure` with the plugin-specific state * @param cls the `struct PostgresClosure` with the plugin-specific state
* @param session connection to the database * @param session connection to the database
* @param exchange_timestamp time the exchange received the deposit request
* @param deposit deposit information to store * @param deposit deposit information to store
* @return query result status * @return query result status
*/ */
static enum GNUNET_DB_QueryStatus static enum GNUNET_DB_QueryStatus
postgres_insert_deposit (void *cls, postgres_insert_deposit (void *cls,
struct TALER_EXCHANGEDB_Session *session, struct TALER_EXCHANGEDB_Session *session,
struct GNUNET_TIME_Absolute exchange_timestamp,
const struct TALER_EXCHANGEDB_Deposit *deposit) const struct TALER_EXCHANGEDB_Deposit *deposit)
{ {
struct GNUNET_PQ_QueryParam params[] = { struct GNUNET_PQ_QueryParam params[] = {
@ -3229,6 +3266,7 @@ postgres_insert_deposit (void *cls,
GNUNET_PQ_query_param_auto_from_type (&deposit->h_wire), GNUNET_PQ_query_param_auto_from_type (&deposit->h_wire),
GNUNET_PQ_query_param_auto_from_type (&deposit->csig), GNUNET_PQ_query_param_auto_from_type (&deposit->csig),
TALER_PQ_query_param_json (deposit->receiver_wire_account), TALER_PQ_query_param_json (deposit->receiver_wire_account),
TALER_PQ_query_param_absolute_time (&exchange_timestamp),
GNUNET_PQ_query_param_end GNUNET_PQ_query_param_end
}; };
@ -4042,7 +4080,7 @@ add_coin_deposit (void *cls,
&deposit->amount_with_fee), &deposit->amount_with_fee),
TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit", TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit",
&deposit->deposit_fee), &deposit->deposit_fee),
TALER_PQ_result_spec_absolute_time ("timestamp", TALER_PQ_result_spec_absolute_time ("wallet_timestamp",
&deposit->timestamp), &deposit->timestamp),
TALER_PQ_result_spec_absolute_time ("refund_deadline", TALER_PQ_result_spec_absolute_time ("refund_deadline",
&deposit->refund_deadline), &deposit->refund_deadline),
@ -5462,14 +5500,17 @@ deposit_serial_helper_cb (void *cls,
for (unsigned int i = 0; i<num_results; i++) for (unsigned int i = 0; i<num_results; i++)
{ {
struct TALER_EXCHANGEDB_Deposit deposit; struct TALER_EXCHANGEDB_Deposit deposit;
struct GNUNET_TIME_Absolute exchange_timestamp;
struct TALER_DenominationPublicKey denom_pub; struct TALER_DenominationPublicKey denom_pub;
uint8_t done = 0; uint8_t done = 0;
uint64_t rowid; uint64_t rowid;
struct GNUNET_PQ_ResultSpec rs[] = { struct GNUNET_PQ_ResultSpec rs[] = {
TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
&deposit.amount_with_fee), &deposit.amount_with_fee),
TALER_PQ_result_spec_absolute_time ("timestamp", TALER_PQ_result_spec_absolute_time ("wallet_timestamp",
&deposit.timestamp), &deposit.timestamp),
TALER_PQ_result_spec_absolute_time ("exchange_timestamp",
&exchange_timestamp),
GNUNET_PQ_result_spec_auto_from_type ("merchant_pub", GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
&deposit.merchant_pub), &deposit.merchant_pub),
GNUNET_PQ_result_spec_rsa_public_key ("denom_pub", GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
@ -5505,6 +5546,7 @@ deposit_serial_helper_cb (void *cls,
} }
ret = dsc->cb (dsc->cb_cls, ret = dsc->cb (dsc->cb_cls,
rowid, rowid,
exchange_timestamp,
deposit.timestamp, deposit.timestamp,
&deposit.merchant_pub, &deposit.merchant_pub,
&denom_pub, &denom_pub,

View File

@ -833,6 +833,8 @@ static uint64_t deposit_rowid;
* @param cls closure a `struct TALER_EXCHANGEDB_Deposit *` * @param cls closure a `struct TALER_EXCHANGEDB_Deposit *`
* @param rowid unique ID for the deposit in our DB, used for marking * @param rowid unique ID for the deposit in our DB, used for marking
* it as 'tiny' or 'done' * it as 'tiny' or 'done'
* @param exchange_timestamp when did the deposit happen
* @param wallet_timestamp when did the wallet sign the contract
* @param merchant_pub public key of the merchant * @param merchant_pub public key of the merchant
* @param coin_pub public key of the coin * @param coin_pub public key of the coin
* @param amount_with_fee amount that was deposited including fee * @param amount_with_fee amount that was deposited including fee
@ -846,6 +848,8 @@ static uint64_t deposit_rowid;
static enum GNUNET_DB_QueryStatus static enum GNUNET_DB_QueryStatus
deposit_cb (void *cls, deposit_cb (void *cls,
uint64_t rowid, uint64_t rowid,
struct GNUNET_TIME_Absolute exchange_timestamp,
struct GNUNET_TIME_Absolute wallet_timestamp,
const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_Amount *amount_with_fee, const struct TALER_Amount *amount_with_fee,
@ -890,7 +894,8 @@ deposit_cb (void *cls,
* *
* @param cls closure * @param cls closure
* @param rowid unique serial ID for the deposit in our DB * @param rowid unique serial ID for the deposit in our DB
* @param timestamp when did the deposit happen * @param exchange_timestamp when did the deposit happen
* @param wallet_timestamp when did the wallet sign the contract
* @param merchant_pub public key of the merchant * @param merchant_pub public key of the merchant
* @param denom_pub denomination of the @a coin_pub * @param denom_pub denomination of the @a coin_pub
* @param coin_pub public key of the coin * @param coin_pub public key of the coin
@ -908,7 +913,8 @@ deposit_cb (void *cls,
static int static int
audit_deposit_cb (void *cls, audit_deposit_cb (void *cls,
uint64_t rowid, uint64_t rowid,
struct GNUNET_TIME_Absolute timestamp, struct GNUNET_TIME_Absolute exchange_timestamp,
struct GNUNET_TIME_Absolute wallet_timestamp,
const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_DenominationPublicKey *denom_pub,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
@ -1878,15 +1884,27 @@ run (void *cls)
plugin->ensure_coin_known (plugin->cls, plugin->ensure_coin_known (plugin->cls,
session, session,
&deposit.coin)); &deposit.coin));
{
struct GNUNET_TIME_Absolute now;
struct GNUNET_TIME_Absolute r;
struct TALER_Amount deposit_fee;
now = GNUNET_TIME_absolute_get ();
GNUNET_TIME_round_abs (&now);
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->insert_deposit (plugin->cls, plugin->insert_deposit (plugin->cls,
session, session,
now,
&deposit)); &deposit));
FAILIF (1 != FAILIF (1 !=
plugin->have_deposit (plugin->cls, plugin->have_deposit (plugin->cls,
session, session,
&deposit, &deposit,
GNUNET_YES)); GNUNET_YES,
&deposit_fee,
&r));
FAILIF (now.abs_value_us != r.abs_value_us);
}
{ {
struct GNUNET_TIME_Absolute start_range; struct GNUNET_TIME_Absolute start_range;
struct GNUNET_TIME_Absolute end_range; struct GNUNET_TIME_Absolute end_range;
@ -1983,18 +2001,27 @@ run (void *cls)
session, session,
"test-2")); "test-2"));
RND_BLK (&deposit2.merchant_pub); /* should fail if merchant is different */ RND_BLK (&deposit2.merchant_pub); /* should fail if merchant is different */
{
struct GNUNET_TIME_Absolute r;
struct TALER_Amount deposit_fee;
FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
plugin->have_deposit (plugin->cls, plugin->have_deposit (plugin->cls,
session, session,
&deposit2, &deposit2,
GNUNET_YES)); GNUNET_YES,
&deposit_fee,
&r));
deposit2.merchant_pub = deposit.merchant_pub; deposit2.merchant_pub = deposit.merchant_pub;
RND_BLK (&deposit2.coin.coin_pub); /* should fail if coin is different */ RND_BLK (&deposit2.coin.coin_pub); /* should fail if coin is different */
FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
plugin->have_deposit (plugin->cls, plugin->have_deposit (plugin->cls,
session, session,
&deposit2, &deposit2,
GNUNET_YES)); GNUNET_YES,
&deposit_fee,
&r));
}
FAILIF (GNUNET_OK != FAILIF (GNUNET_OK !=
test_melting (session)); test_melting (session));
FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=

View File

@ -300,9 +300,9 @@ struct TALER_AUDITORDB_DepositConfirmation
struct GNUNET_HashCode h_wire; struct GNUNET_HashCode h_wire;
/** /**
* Time when this confirmation was generated. * Time when this deposit confirmation was generated by the exchange.
*/ */
struct GNUNET_TIME_Absolute timestamp; struct GNUNET_TIME_Absolute exchange_timestamp;
/** /**
* How much time does the @e merchant have to issue a refund * How much time does the @e merchant have to issue a refund

View File

@ -1542,73 +1542,92 @@ enum TALER_ErrorCode
* This response is provided with HTTP status code * This response is provided with HTTP status code
* #MHD_HTTP_SERVICE_UNAVAILABLE. * #MHD_HTTP_SERVICE_UNAVAILABLE.
*/ */
TALER_EC_TRACK_TRANSFER_EXCHANGE_TIMEOUT = 2400, TALER_EC_POST_TRANSFERS_EXCHANGE_TIMEOUT = 2400,
/** /**
* We failed to obtain an acceptable /keys response from the exchange * We failed to obtain an acceptable /keys response from the exchange
* for the /track/transfer request. This response is provided with * for the /track/transfer request. This response is provided with
* HTTP status code #MHD_HTTP_FAILED_DEPENDENCY. * HTTP status code #MHD_HTTP_FAILED_DEPENDENCY.
*/ */
TALER_EC_TRACK_TRANSFER_EXCHANGE_KEYS_FAILURE = 2401, TALER_EC_POST_TRANSFERS_EXCHANGE_KEYS_FAILURE = 2401,
/** /**
* We failed to persist coin wire transfer information in our merchant * We failed to persist coin wire transfer information in our merchant
* database. The response is provided with HTTP status code * database. The response is provided with HTTP status code
* #MHD_HTTP_INTERNAL_SERVER_ERROR. * #MHD_HTTP_INTERNAL_SERVER_ERROR.
*/ */
TALER_EC_TRACK_TRANSFER_DB_STORE_COIN_ERROR = 2402, TALER_EC_POST_TRANSFERS_DB_STORE_COIN_ERROR = 2402,
/** /**
* We internally failed to execute the /track/transfer request. The * We internally failed to execute the /track/transfer request. The
* response is provided with HTTP status code * response is provided with HTTP status code
* #MHD_HTTP_INTERNAL_SERVER_ERROR. * #MHD_HTTP_INTERNAL_SERVER_ERROR.
*/ */
TALER_EC_TRACK_TRANSFER_REQUEST_ERROR = 2403, TALER_EC_POST_TRANSFERS_REQUEST_ERROR = 2403,
/** /**
* We failed to persist wire transfer information in our merchant * We failed to persist wire transfer information in our merchant
* database. The response is provided with HTTP status code * database. The response is provided with HTTP status code
* #MHD_HTTP_INTERNAL_SERVER_ERROR. * #MHD_HTTP_INTERNAL_SERVER_ERROR.
*/ */
TALER_EC_TRACK_TRANSFER_DB_STORE_TRANSFER_ERROR = 2404, TALER_EC_POST_TRANSFERS_DB_STORE_TRANSFER_ERROR = 2404,
/** /**
* The exchange returned an error from /track/transfer. The response * The exchange returned an error from /track/transfer. The response
* is provided with HTTP status code #MHD_HTTP_FAILED_DEPENDENCY. * is provided with HTTP status code #MHD_HTTP_FAILED_DEPENDENCY.
*/ */
TALER_EC_TRACK_TRANSFER_EXCHANGE_ERROR = 2405, TALER_EC_POST_TRANSFERS_EXCHANGE_ERROR = 2405,
/** /**
* We failed to fetch deposit information from our merchant database. * We failed to fetch deposit information from our merchant database.
* The response is provided with HTTP status code * The response is provided with HTTP status code
* #MHD_HTTP_INTERNAL_SERVER_ERROR. * #MHD_HTTP_INTERNAL_SERVER_ERROR.
*/ */
TALER_EC_TRACK_TRANSFER_DB_FETCH_DEPOSIT_ERROR = 2406, TALER_EC_POST_TRANSFERS_DB_FETCH_DEPOSIT_ERROR = 2406,
/** /**
* We encountered an internal logic error. The response is provided * We encountered an internal logic error. The response is provided
* with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR. * with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
*/ */
TALER_EC_TRACK_TRANSFER_DB_INTERNAL_LOGIC_ERROR = 2407, TALER_EC_POST_TRANSFERS_DB_INTERNAL_LOGIC_ERROR = 2407,
/** /**
* The exchange gave conflicting information about a coin which has * The exchange gave conflicting information about a coin which has
* been wire transferred. The response is provided with HTTP status * been wire transferred. The response is provided with HTTP status
* code #MHD_HTTP_FAILED_DEPENDENCY. * code #MHD_HTTP_FAILED_DEPENDENCY.
*/ */
TALER_EC_TRACK_TRANSFER_CONFLICTING_REPORTS = 2408, TALER_EC_POST_TRANSFERS_CONFLICTING_REPORTS = 2408,
/** /**
* The merchant backend had problems in creating the JSON response. * The merchant backend had problems in creating the JSON response.
*/ */
TALER_EC_TRACK_TRANSFER_JSON_RESPONSE_ERROR = 2409, TALER_EC_POST_TRANSFERS_JSON_RESPONSE_ERROR = 2409,
/** /**
* The exchange charged a different wire fee than what it originally * The exchange charged a different wire fee than what it originally
* advertised, and it is higher. The response is provied with an HTTP * advertised, and it is higher. The response is provided with an
* status of #MHD_HTTP_FAILED_DEPENDENCY. * HTTP status of #MHD_HTTP_FAILED_DEPENDENCY.
*/ */
TALER_EC_TRACK_TRANSFER_JSON_BAD_WIRE_FEE = 2410, TALER_EC_POST_TRANSFERS_JSON_BAD_WIRE_FEE = 2410,
/**
* We did not find the account that the transfer was made to. The
* response is provided with an HTTP status of #MHD_HTTP_NOT_FOUND.
*/
TALER_EC_POST_TRANSFERS_ACCOUNT_NOT_FOUND = 2411,
/**
* We did failed to store information in our database. The response is
* provided with an HTTP status of #MHD_HTTP_INTERNAL_SERVER_ERROR.
*/
TALER_EC_POST_TRANSFERS_DB_STORE_ERROR = 2412,
/**
* We did failed to retrieve information from our database. The
* response is provided with an HTTP status of
* #MHD_HTTP_INTERNAL_SERVER_ERROR.
*/
TALER_EC_POST_TRANSFERS_DB_LOOKUP_ERROR = 2413,
/** /**
* The merchant backend cannot create an instance under the given * The merchant backend cannot create an instance under the given

View File

@ -756,6 +756,7 @@ struct TALER_EXCHANGE_DepositHandle;
* *
* @param cls closure * @param cls closure
* @param hr HTTP response data * @param hr HTTP response data
* @param deposit_timestamp time when the exchange generated the deposit confirmation
* @param exchange_sig signature provided by the exchange * @param exchange_sig signature provided by the exchange
* @param exchange_pub exchange key used to sign @a obj, or NULL * @param exchange_pub exchange key used to sign @a obj, or NULL
*/ */
@ -763,6 +764,7 @@ typedef void
(*TALER_EXCHANGE_DepositResultCallback) ( (*TALER_EXCHANGE_DepositResultCallback) (
void *cls, void *cls,
const struct TALER_EXCHANGE_HttpResponse *hr, const struct TALER_EXCHANGE_HttpResponse *hr,
struct GNUNET_TIME_Absolute deposit_timestamp,
const struct TALER_ExchangeSignatureP *exchange_sig, const struct TALER_ExchangeSignatureP *exchange_sig,
const struct TALER_ExchangePublicKeyP *exchange_pub); const struct TALER_ExchangePublicKeyP *exchange_pub);

View File

@ -975,6 +975,8 @@ struct TALER_EXCHANGEDB_Session;
* @param cls closure * @param cls closure
* @param rowid unique ID for the deposit in our DB, used for marking * @param rowid unique ID for the deposit in our DB, used for marking
* it as 'tiny' or 'done' * it as 'tiny' or 'done'
* @param exchange_timestamp when did the exchange receive the deposit
* @param wallet_timestamp when did the wallet sign the contract
* @param merchant_pub public key of the merchant * @param merchant_pub public key of the merchant
* @param coin_pub public key of the coin * @param coin_pub public key of the coin
* @param amount_with_fee amount that was deposited including fee * @param amount_with_fee amount that was deposited including fee
@ -990,6 +992,8 @@ typedef enum GNUNET_DB_QueryStatus
(*TALER_EXCHANGEDB_DepositIterator)( (*TALER_EXCHANGEDB_DepositIterator)(
void *cls, void *cls,
uint64_t rowid, uint64_t rowid,
struct GNUNET_TIME_Absolute exchange_timestamp,
struct GNUNET_TIME_Absolute wallet_timestamp,
const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_Amount *amount_with_fee, const struct TALER_Amount *amount_with_fee,
@ -1022,7 +1026,8 @@ typedef void
* *
* @param cls closure * @param cls closure
* @param rowid unique serial ID for the deposit in our DB * @param rowid unique serial ID for the deposit in our DB
* @param timestamp when did the deposit happen * @param exchange_timestamp when did the deposit happen
* @param wallet_timestamp when did the contract happen
* @param merchant_pub public key of the merchant * @param merchant_pub public key of the merchant
* @param denom_pub denomination public key of @a coin_pub * @param denom_pub denomination public key of @a coin_pub
* @param coin_pub public key of the coin * @param coin_pub public key of the coin
@ -1042,7 +1047,8 @@ typedef int
(*TALER_EXCHANGEDB_DepositCallback)( (*TALER_EXCHANGEDB_DepositCallback)(
void *cls, void *cls,
uint64_t rowid, uint64_t rowid,
struct GNUNET_TIME_Absolute timestamp, struct GNUNET_TIME_Absolute exchange_timestamp,
struct GNUNET_TIME_Absolute wallet_timestamp,
const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_DenominationPublicKey *denom_pub,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
@ -1841,6 +1847,8 @@ struct TALER_EXCHANGEDB_Plugin
* @param session database connection * @param session database connection
* @param deposit deposit to search for * @param deposit deposit to search for
* @param check_extras whether to check extra fields or not * @param check_extras whether to check extra fields or not
* @param[out] deposit_fee set to the deposit fee the exchange charged
* @param[out] exchange_timestamp set to the time when the exchange received the deposit
* @return 1 if we know this operation, * @return 1 if we know this operation,
* 0 if this exact deposit is unknown to us, * 0 if this exact deposit is unknown to us,
* otherwise transaction error status * otherwise transaction error status
@ -1849,7 +1857,9 @@ struct TALER_EXCHANGEDB_Plugin
(*have_deposit)(void *cls, (*have_deposit)(void *cls,
struct TALER_EXCHANGEDB_Session *session, struct TALER_EXCHANGEDB_Session *session,
const struct TALER_EXCHANGEDB_Deposit *deposit, const struct TALER_EXCHANGEDB_Deposit *deposit,
int check_extras); int check_extras,
struct TALER_Amount *deposit_fee,
struct GNUNET_TIME_Absolute *exchange_timestamp);
/** /**
@ -1857,12 +1867,14 @@ struct TALER_EXCHANGEDB_Plugin
* *
* @param cls the @e cls of this struct with the plugin-specific state * @param cls the @e cls of this struct with the plugin-specific state
* @param session connection to the database * @param session connection to the database
* @param exchange_timestamp time the exchange received the deposit request
* @param deposit deposit information to store * @param deposit deposit information to store
* @return query result status * @return query result status
*/ */
enum GNUNET_DB_QueryStatus enum GNUNET_DB_QueryStatus
(*insert_deposit)(void *cls, (*insert_deposit)(void *cls,
struct TALER_EXCHANGEDB_Session *session, struct TALER_EXCHANGEDB_Session *session,
struct GNUNET_TIME_Absolute exchange_timestamp,
const struct TALER_EXCHANGEDB_Deposit *deposit); const struct TALER_EXCHANGEDB_Deposit *deposit);

View File

@ -363,7 +363,7 @@ struct TALER_DepositRequestPS
* deposit request in a timely fashion (so back-dating is not * deposit request in a timely fashion (so back-dating is not
* prevented). * prevented).
*/ */
struct GNUNET_TIME_AbsoluteNBO timestamp; struct GNUNET_TIME_AbsoluteNBO wallet_timestamp;
/** /**
* How much time does the merchant have to issue a refund request? * How much time does the merchant have to issue a refund request?
@ -429,9 +429,10 @@ struct TALER_DepositConfirmationPS
struct GNUNET_HashCode h_wire GNUNET_PACKED; struct GNUNET_HashCode h_wire GNUNET_PACKED;
/** /**
* Time when this confirmation was generated. * Time when this confirmation was generated / when the exchange received
* the deposit request.
*/ */
struct GNUNET_TIME_AbsoluteNBO timestamp; struct GNUNET_TIME_AbsoluteNBO exchange_timestamp;
/** /**
* How much time does the @e merchant have to issue a refund * How much time does the @e merchant have to issue a refund

View File

@ -1903,6 +1903,7 @@ TALER_TESTING_cmd_connect_with_state (const char *label,
* @param dbc collects plugin and session handles * @param dbc collects plugin and session handles
* @param merchant_name Human-readable name of the merchant. * @param merchant_name Human-readable name of the merchant.
* @param merchant_account merchant's account name (NOT a payto:// URI) * @param merchant_account merchant's account name (NOT a payto:// URI)
* @param exchange_timestamp when did the exchange receive the deposit
* @param wire_deadline point in time where the aggregator should have * @param wire_deadline point in time where the aggregator should have
* wired money to the merchant. * wired money to the merchant.
* @param amount_with_fee amount to deposit (inclusive of deposit fee) * @param amount_with_fee amount to deposit (inclusive of deposit fee)
@ -1910,11 +1911,12 @@ TALER_TESTING_cmd_connect_with_state (const char *label,
* @return the command. * @return the command.
*/ */
struct TALER_TESTING_Command struct TALER_TESTING_Command
TALER_TESTING_cmd_insert_deposit (const char *label, TALER_TESTING_cmd_insert_deposit (
const struct const char *label,
TALER_TESTING_DatabaseConnection *dbc, const struct TALER_TESTING_DatabaseConnection *dbc,
const char *merchant_name, const char *merchant_name,
const char *merchant_account, const char *merchant_account,
struct GNUNET_TIME_Absolute exchange_timestamp,
struct GNUNET_TIME_Relative wire_deadline, struct GNUNET_TIME_Relative wire_deadline,
const char *amount_with_fee, const char *amount_with_fee,
const char *deposit_fee); const char *deposit_fee);

View File

@ -148,7 +148,7 @@ handle_deposit_confirmation_finished (void *cls,
* *
* @param h_wire hash of merchant wire details * @param h_wire hash of merchant wire details
* @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the auditor) * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the auditor)
* @param timestamp timestamp when the contract was finalized, must not be too far in the future * @param exchange_timestamp timestamp when the deposit was received by the wallet
* @param refund_deadline date until which the merchant can issue a refund to the customer via the auditor (can be zero if refunds are not allowed); must not be after the @a wire_deadline * @param refund_deadline date until which the merchant can issue a refund to the customer via the auditor (can be zero if refunds are not allowed); must not be after the @a wire_deadline
* @param amount_without_fee the amount confirmed to be wired by the exchange to the merchant * @param amount_without_fee the amount confirmed to be wired by the exchange to the merchant
* @param coin_pub coins public key * @param coin_pub coins public key
@ -165,7 +165,7 @@ handle_deposit_confirmation_finished (void *cls,
static int static int
verify_signatures (const struct GNUNET_HashCode *h_wire, verify_signatures (const struct GNUNET_HashCode *h_wire,
const struct GNUNET_HashCode *h_contract_terms, const struct GNUNET_HashCode *h_contract_terms,
struct GNUNET_TIME_Absolute timestamp, struct GNUNET_TIME_Absolute exchange_timestamp,
struct GNUNET_TIME_Absolute refund_deadline, struct GNUNET_TIME_Absolute refund_deadline,
const struct TALER_Amount *amount_without_fee, const struct TALER_Amount *amount_without_fee,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
@ -184,7 +184,7 @@ verify_signatures (const struct GNUNET_HashCode *h_wire,
.purpose.size = htonl (sizeof (dc)), .purpose.size = htonl (sizeof (dc)),
.h_contract_terms = *h_contract_terms, .h_contract_terms = *h_contract_terms,
.h_wire = *h_wire, .h_wire = *h_wire,
.timestamp = GNUNET_TIME_absolute_hton (timestamp), .exchange_timestamp = GNUNET_TIME_absolute_hton (exchange_timestamp),
.refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline), .refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline),
.coin_pub = *coin_pub, .coin_pub = *coin_pub,
.merchant = *merchant_pub .merchant = *merchant_pub
@ -256,7 +256,7 @@ verify_signatures (const struct GNUNET_HashCode *h_wire,
* @param auditor the auditor handle; the auditor must be ready to operate * @param auditor the auditor handle; the auditor must be ready to operate
* @param h_wire hash of merchant wire details * @param h_wire hash of merchant wire details
* @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the auditor) * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the auditor)
* @param timestamp timestamp when the contract was finalized, must not be too far in the future * @param exchange_timestamp timestamp when deposit was received by the exchange
* @param refund_deadline date until which the merchant can issue a refund to the customer via the auditor (can be zero if refunds are not allowed); must not be after the @a wire_deadline * @param refund_deadline date until which the merchant can issue a refund to the customer via the auditor (can be zero if refunds are not allowed); must not be after the @a wire_deadline
* @param amount_without_fee the amount confirmed to be wired by the exchange to the merchant * @param amount_without_fee the amount confirmed to be wired by the exchange to the merchant
* @param coin_pub coins public key * @param coin_pub coins public key
@ -278,7 +278,7 @@ TALER_AUDITOR_deposit_confirmation (
struct TALER_AUDITOR_Handle *auditor, struct TALER_AUDITOR_Handle *auditor,
const struct GNUNET_HashCode *h_wire, const struct GNUNET_HashCode *h_wire,
const struct GNUNET_HashCode *h_contract_terms, const struct GNUNET_HashCode *h_contract_terms,
struct GNUNET_TIME_Absolute timestamp, struct GNUNET_TIME_Absolute exchange_timestamp,
struct GNUNET_TIME_Absolute refund_deadline, struct GNUNET_TIME_Absolute refund_deadline,
const struct TALER_Amount *amount_without_fee, const struct TALER_Amount *amount_without_fee,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
@ -298,7 +298,7 @@ TALER_AUDITOR_deposit_confirmation (
json_t *deposit_confirmation_obj; json_t *deposit_confirmation_obj;
CURL *eh; CURL *eh;
(void) GNUNET_TIME_round_abs (&timestamp); (void) GNUNET_TIME_round_abs (&exchange_timestamp);
(void) GNUNET_TIME_round_abs (&refund_deadline); (void) GNUNET_TIME_round_abs (&refund_deadline);
(void) GNUNET_TIME_round_abs (&ep_start); (void) GNUNET_TIME_round_abs (&ep_start);
(void) GNUNET_TIME_round_abs (&ep_expire); (void) GNUNET_TIME_round_abs (&ep_expire);
@ -308,7 +308,7 @@ TALER_AUDITOR_deposit_confirmation (
if (GNUNET_OK != if (GNUNET_OK !=
verify_signatures (h_wire, verify_signatures (h_wire,
h_contract_terms, h_contract_terms,
timestamp, exchange_timestamp,
refund_deadline, refund_deadline,
amount_without_fee, amount_without_fee,
coin_pub, coin_pub,
@ -336,7 +336,8 @@ TALER_AUDITOR_deposit_confirmation (
"h_wire", GNUNET_JSON_from_data_auto (h_wire), "h_wire", GNUNET_JSON_from_data_auto (h_wire),
"h_contract_terms", GNUNET_JSON_from_data_auto ( "h_contract_terms", GNUNET_JSON_from_data_auto (
h_contract_terms), h_contract_terms),
"timestamp", GNUNET_JSON_from_time_abs (timestamp), "exchange_timestamp", GNUNET_JSON_from_time_abs (
exchange_timestamp),
"refund_deadline", GNUNET_JSON_from_time_abs (refund_deadline), "refund_deadline", GNUNET_JSON_from_time_abs (refund_deadline),
"amount_without_fee", TALER_JSON_from_amount ( "amount_without_fee", TALER_JSON_from_amount (
amount_without_fee), amount_without_fee),

View File

@ -524,7 +524,7 @@ TALER_EXCHANGE_verify_coin_history (
GNUNET_JSON_spec_fixed_auto ("h_wire", GNUNET_JSON_spec_fixed_auto ("h_wire",
&dr.h_wire), &dr.h_wire),
GNUNET_JSON_spec_absolute_time_nbo ("timestamp", GNUNET_JSON_spec_absolute_time_nbo ("timestamp",
&dr.timestamp), &dr.wallet_timestamp),
GNUNET_JSON_spec_absolute_time_nbo ("refund_deadline", GNUNET_JSON_spec_absolute_time_nbo ("refund_deadline",
&dr.refund_deadline), &dr.refund_deadline),
TALER_JSON_spec_amount_nbo ("deposit_fee", TALER_JSON_spec_amount_nbo ("deposit_fee",

View File

@ -160,7 +160,7 @@ auditor_cb (void *cls,
ah, ah,
&dh->depconf.h_wire, &dh->depconf.h_wire,
&dh->depconf.h_contract_terms, &dh->depconf.h_contract_terms,
GNUNET_TIME_absolute_ntoh (dh->depconf.timestamp), GNUNET_TIME_absolute_ntoh (dh->depconf.exchange_timestamp),
GNUNET_TIME_absolute_ntoh (dh->depconf.refund_deadline), GNUNET_TIME_absolute_ntoh (dh->depconf.refund_deadline),
&amount_without_fee, &amount_without_fee,
&dh->depconf.coin_pub, &dh->depconf.coin_pub,
@ -198,6 +198,8 @@ verify_deposit_signature_ok (struct TALER_EXCHANGE_DepositHandle *dh,
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("exchange_sig", exchange_sig), GNUNET_JSON_spec_fixed_auto ("exchange_sig", exchange_sig),
GNUNET_JSON_spec_fixed_auto ("exchange_pub", exchange_pub), GNUNET_JSON_spec_fixed_auto ("exchange_pub", exchange_pub),
GNUNET_JSON_spec_absolute_time_nbo ("exchange_timestamp",
&dh->depconf.exchange_timestamp),
GNUNET_JSON_spec_end () GNUNET_JSON_spec_end ()
}; };
@ -386,6 +388,7 @@ handle_deposit_finished (void *cls,
} }
dh->cb (dh->cb_cls, dh->cb (dh->cb_cls,
&hr, &hr,
GNUNET_TIME_absolute_ntoh (dh->depconf.exchange_timestamp),
es, es,
ep); ep);
TALER_EXCHANGE_deposit_cancel (dh); TALER_EXCHANGE_deposit_cancel (dh);
@ -429,7 +432,7 @@ verify_signatures (const struct TALER_EXCHANGE_DenomPublicKey *dki,
.purpose.size = htonl (sizeof (dr)), .purpose.size = htonl (sizeof (dr)),
.h_contract_terms = *h_contract_terms, .h_contract_terms = *h_contract_terms,
.h_wire = *h_wire, .h_wire = *h_wire,
.timestamp = GNUNET_TIME_absolute_hton (timestamp), .wallet_timestamp = GNUNET_TIME_absolute_hton (timestamp),
.refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline), .refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline),
.merchant = *merchant_pub, .merchant = *merchant_pub,
.coin_pub = *coin_pub .coin_pub = *coin_pub
@ -658,7 +661,7 @@ TALER_EXCHANGE_deposit (struct TALER_EXCHANGE_Handle *exchange,
TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT); TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT);
dh->depconf.h_contract_terms = *h_contract_terms; dh->depconf.h_contract_terms = *h_contract_terms;
dh->depconf.h_wire = h_wire; dh->depconf.h_wire = h_wire;
dh->depconf.timestamp = GNUNET_TIME_absolute_hton (timestamp); /* dh->depconf.exchange_timestamp; -- initialized later from exchange reply! */
dh->depconf.refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline); dh->depconf.refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline);
TALER_amount_hton (&dh->depconf.amount_without_fee, TALER_amount_hton (&dh->depconf.amount_without_fee,
&amount_without_fee); &amount_without_fee);

View File

@ -148,7 +148,8 @@ handle_refund_finished (void *cls,
struct TALER_ExchangeSignatureP exchange_sig; struct TALER_ExchangeSignatureP exchange_sig;
struct TALER_ExchangePublicKeyP *ep = NULL; struct TALER_ExchangePublicKeyP *ep = NULL;
struct TALER_ExchangeSignatureP *es = NULL; struct TALER_ExchangeSignatureP *es = NULL;
struct TALER_Amount *rf = NULL; struct TALER_Amount ra;
const struct TALER_Amount *rf = NULL;
const json_t *j = response; const json_t *j = response;
struct TALER_EXCHANGE_HttpResponse hr = { struct TALER_EXCHANGE_HttpResponse hr = {
.reply = j, .reply = j,
@ -176,7 +177,9 @@ handle_refund_finished (void *cls,
{ {
ep = &exchange_pub; ep = &exchange_pub;
es = &exchange_sig; es = &exchange_sig;
rf = &rh->depconf.refund_fee; TALER_amount_ntoh (&ra,
&rh->depconf.refund_fee);
rf = &ra;
} }
break; break;
case MHD_HTTP_BAD_REQUEST: case MHD_HTTP_BAD_REQUEST:

View File

@ -108,6 +108,7 @@ run (void *cls,
&dbc, &dbc,
"bob", "bob",
USER42_ACCOUNT, USER42_ACCOUNT,
GNUNET_TIME_absolute_get (),
GNUNET_TIME_UNIT_ZERO, GNUNET_TIME_UNIT_ZERO,
"EUR:1", "EUR:1",
"EUR:0.1"), "EUR:0.1"),
@ -126,6 +127,7 @@ run (void *cls,
&dbc, &dbc,
"bob", "bob",
USER42_ACCOUNT, USER42_ACCOUNT,
GNUNET_TIME_absolute_get (),
GNUNET_TIME_UNIT_ZERO, GNUNET_TIME_UNIT_ZERO,
"EUR:1", "EUR:1",
"EUR:0.1"), "EUR:0.1"),
@ -134,6 +136,7 @@ run (void *cls,
&dbc, &dbc,
"bob", "bob",
USER42_ACCOUNT, USER42_ACCOUNT,
GNUNET_TIME_absolute_get (),
GNUNET_TIME_UNIT_ZERO, GNUNET_TIME_UNIT_ZERO,
"EUR:1", "EUR:1",
"EUR:0.1"), "EUR:0.1"),
@ -153,6 +156,7 @@ run (void *cls,
&dbc, &dbc,
"bob", "bob",
"4", "4",
GNUNET_TIME_absolute_get (),
GNUNET_TIME_UNIT_ZERO, GNUNET_TIME_UNIT_ZERO,
"EUR:1", "EUR:1",
"EUR:0.1"), "EUR:0.1"),
@ -160,6 +164,7 @@ run (void *cls,
&dbc, &dbc,
"bob", "bob",
"5", "5",
GNUNET_TIME_absolute_get (),
GNUNET_TIME_UNIT_ZERO, GNUNET_TIME_UNIT_ZERO,
"EUR:1", "EUR:1",
"EUR:0.1"), "EUR:0.1"),
@ -167,6 +172,7 @@ run (void *cls,
&dbc, &dbc,
"alice", "alice",
"4", "4",
GNUNET_TIME_absolute_get (),
GNUNET_TIME_UNIT_ZERO, GNUNET_TIME_UNIT_ZERO,
"EUR:1", "EUR:1",
"EUR:0.1"), "EUR:0.1"),
@ -195,6 +201,7 @@ run (void *cls,
&dbc, &dbc,
"bob", "bob",
USER42_ACCOUNT, USER42_ACCOUNT,
GNUNET_TIME_absolute_get (),
GNUNET_TIME_relative_multiply GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_SECONDS, (GNUNET_TIME_UNIT_SECONDS,
5), 5),
@ -204,6 +211,7 @@ run (void *cls,
&dbc, &dbc,
"bob", "bob",
USER42_ACCOUNT, USER42_ACCOUNT,
GNUNET_TIME_absolute_get (),
GNUNET_TIME_relative_multiply GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_SECONDS, (GNUNET_TIME_UNIT_SECONDS,
5), 5),
@ -229,6 +237,7 @@ run (void *cls,
&dbc, &dbc,
"bob", "bob",
USER42_ACCOUNT, USER42_ACCOUNT,
GNUNET_TIME_absolute_get (),
GNUNET_TIME_relative_multiply GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_SECONDS, (GNUNET_TIME_UNIT_SECONDS,
10), 10),
@ -239,6 +248,7 @@ run (void *cls,
&dbc, &dbc,
"bob", "bob",
USER42_ACCOUNT, USER42_ACCOUNT,
GNUNET_TIME_absolute_get (),
GNUNET_TIME_relative_multiply GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_SECONDS, (GNUNET_TIME_UNIT_SECONDS,
5), 5),
@ -263,6 +273,7 @@ run (void *cls,
&dbc, &dbc,
"bob", "bob",
USER42_ACCOUNT, USER42_ACCOUNT,
GNUNET_TIME_absolute_get (),
GNUNET_TIME_UNIT_ZERO, GNUNET_TIME_UNIT_ZERO,
"EUR:0.102", "EUR:0.102",
"EUR:0.1"), "EUR:0.1"),
@ -274,6 +285,7 @@ run (void *cls,
&dbc, &dbc,
"bob", "bob",
USER42_ACCOUNT, USER42_ACCOUNT,
GNUNET_TIME_absolute_get (),
GNUNET_TIME_UNIT_ZERO, GNUNET_TIME_UNIT_ZERO,
"EUR:0.102", "EUR:0.102",
"EUR:0.1"), "EUR:0.1"),
@ -281,6 +293,7 @@ run (void *cls,
&dbc, &dbc,
"bob", "bob",
USER42_ACCOUNT, USER42_ACCOUNT,
GNUNET_TIME_absolute_get (),
GNUNET_TIME_UNIT_ZERO, GNUNET_TIME_UNIT_ZERO,
"EUR:0.102", "EUR:0.102",
"EUR:0.1"), "EUR:0.1"),
@ -292,6 +305,7 @@ run (void *cls,
&dbc, &dbc,
"bob", "bob",
USER42_ACCOUNT, USER42_ACCOUNT,
GNUNET_TIME_absolute_get (),
GNUNET_TIME_UNIT_ZERO, GNUNET_TIME_UNIT_ZERO,
"EUR:0.102", "EUR:0.102",
"EUR:0.1"), "EUR:0.1"),
@ -303,6 +317,7 @@ run (void *cls,
&dbc, &dbc,
"bob", "bob",
USER42_ACCOUNT, USER42_ACCOUNT,
GNUNET_TIME_absolute_get (),
GNUNET_TIME_UNIT_ZERO, GNUNET_TIME_UNIT_ZERO,
"EUR:0.112", "EUR:0.112",
"EUR:0.1"), "EUR:0.1"),
@ -319,6 +334,7 @@ run (void *cls,
&dbc, &dbc,
"bob", "bob",
USER42_ACCOUNT, USER42_ACCOUNT,
GNUNET_TIME_absolute_get (),
GNUNET_TIME_UNIT_ZERO, GNUNET_TIME_UNIT_ZERO,
"EUR:0.109", "EUR:0.109",
"EUR:0.1"), "EUR:0.1"),
@ -330,6 +346,7 @@ run (void *cls,
&dbc, &dbc,
"bob", "bob",
USER42_ACCOUNT, USER42_ACCOUNT,
GNUNET_TIME_absolute_get (),
GNUNET_TIME_UNIT_ZERO, GNUNET_TIME_UNIT_ZERO,
"EUR:0.119", "EUR:0.119",
"EUR:0.1"), "EUR:0.1"),
@ -346,6 +363,7 @@ run (void *cls,
&dbc, &dbc,
"bob", "bob",
USER42_ACCOUNT, USER42_ACCOUNT,
GNUNET_TIME_absolute_get (),
GNUNET_TIME_UNIT_ZERO, GNUNET_TIME_UNIT_ZERO,
"EUR:0.122", "EUR:0.122",
"EUR:0.1"), "EUR:0.1"),
@ -362,6 +380,7 @@ run (void *cls,
&dbc, &dbc,
"bob", "bob",
USER42_ACCOUNT, USER42_ACCOUNT,
GNUNET_TIME_absolute_get (),
GNUNET_TIME_relative_multiply GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_SECONDS, (GNUNET_TIME_UNIT_SECONDS,
5), 5),
@ -375,6 +394,7 @@ run (void *cls,
&dbc, &dbc,
"bob", "bob",
USER42_ACCOUNT, USER42_ACCOUNT,
GNUNET_TIME_absolute_get (),
GNUNET_TIME_relative_multiply GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_SECONDS, (GNUNET_TIME_UNIT_SECONDS,
5), 5),
@ -390,6 +410,7 @@ run (void *cls,
&dbc, &dbc,
"bob", "bob",
USER42_ACCOUNT, USER42_ACCOUNT,
GNUNET_TIME_absolute_get (),
GNUNET_TIME_UNIT_ZERO, GNUNET_TIME_UNIT_ZERO,
"EUR:0.122", "EUR:0.122",
"EUR:0.1"), "EUR:0.1"),
@ -406,6 +427,7 @@ run (void *cls,
&dbc, &dbc,
"bob", "bob",
USER42_ACCOUNT, USER42_ACCOUNT,
GNUNET_TIME_absolute_get (),
GNUNET_TIME_relative_multiply GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_SECONDS, (GNUNET_TIME_UNIT_SECONDS,
5), 5),
@ -419,6 +441,7 @@ run (void *cls,
&dbc, &dbc,
"bob", "bob",
USER42_ACCOUNT, USER42_ACCOUNT,
GNUNET_TIME_absolute_get (),
GNUNET_TIME_relative_multiply GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_SECONDS, (GNUNET_TIME_UNIT_SECONDS,
5), 5),
@ -434,6 +457,7 @@ run (void *cls,
&dbc, &dbc,
"bob", "bob",
USER42_ACCOUNT, USER42_ACCOUNT,
GNUNET_TIME_absolute_get (),
GNUNET_TIME_UNIT_ZERO, GNUNET_TIME_UNIT_ZERO,
"EUR:0.112", "EUR:0.112",
"EUR:0.1"), "EUR:0.1"),

View File

@ -203,6 +203,7 @@ deposit_confirmation_run (void *cls,
const struct TALER_TESTING_Command *deposit_cmd; const struct TALER_TESTING_Command *deposit_cmd;
struct GNUNET_HashCode h_wire; struct GNUNET_HashCode h_wire;
struct GNUNET_HashCode h_contract_terms; struct GNUNET_HashCode h_contract_terms;
const struct GNUNET_TIME_Absolute *exchange_timestamp = NULL;
struct GNUNET_TIME_Absolute timestamp; struct GNUNET_TIME_Absolute timestamp;
struct GNUNET_TIME_Absolute refund_deadline; struct GNUNET_TIME_Absolute refund_deadline;
struct TALER_Amount amount_without_fee; struct TALER_Amount amount_without_fee;
@ -238,6 +239,11 @@ deposit_confirmation_run (void *cls,
TALER_TESTING_get_trait_exchange_sig (deposit_cmd, TALER_TESTING_get_trait_exchange_sig (deposit_cmd,
dcs->coin_index, dcs->coin_index,
&exchange_sig)); &exchange_sig));
GNUNET_assert (GNUNET_OK ==
TALER_TESTING_get_trait_absolute_time (deposit_cmd,
dcs->coin_index,
&exchange_timestamp));
GNUNET_assert (NULL != exchange_timestamp);
keys = TALER_EXCHANGE_get_keys (dcs->is->exchange); keys = TALER_EXCHANGE_get_keys (dcs->is->exchange);
GNUNET_assert (NULL != keys); GNUNET_assert (NULL != keys);
spk = TALER_EXCHANGE_get_signing_key_info (keys, spk = TALER_EXCHANGE_get_signing_key_info (keys,
@ -309,7 +315,7 @@ deposit_confirmation_run (void *cls,
dcs->dc = TALER_AUDITOR_deposit_confirmation (dcs->auditor, dcs->dc = TALER_AUDITOR_deposit_confirmation (dcs->auditor,
&h_wire, &h_wire,
&h_contract_terms, &h_contract_terms,
timestamp, *exchange_timestamp,
refund_deadline, refund_deadline,
&amount_without_fee, &amount_without_fee,
&coin_pub, &coin_pub,

View File

@ -91,9 +91,9 @@ struct DepositState
struct TALER_EXCHANGE_DepositHandle *dh; struct TALER_EXCHANGE_DepositHandle *dh;
/** /**
* Timestamp of the /deposit operation. * Timestamp of the /deposit operation in the wallet (contract signing time).
*/ */
struct GNUNET_TIME_Absolute timestamp; struct GNUNET_TIME_Absolute wallet_timestamp;
/** /**
* Interpreter state. * Interpreter state.
@ -126,6 +126,11 @@ struct DepositState
*/ */
int deposit_succeeded; int deposit_succeeded;
/**
* When did the exchange receive the deposit?
*/
struct GNUNET_TIME_Absolute exchange_timestamp;
/** /**
* Signing key used by the exchange to sign the * Signing key used by the exchange to sign the
* deposit confirmation. * deposit confirmation.
@ -198,6 +203,7 @@ do_retry (void *cls)
* *
* @param cls closure. * @param cls closure.
* @param hr HTTP response details * @param hr HTTP response details
* @param exchange_timestamp when did the exchange receive the deposit permission
* @param exchange_sig signature provided by the exchange * @param exchange_sig signature provided by the exchange
* (NULL on errors) * (NULL on errors)
* @param exchange_pub public key of the exchange, * @param exchange_pub public key of the exchange,
@ -206,6 +212,7 @@ do_retry (void *cls)
static void static void
deposit_cb (void *cls, deposit_cb (void *cls,
const struct TALER_EXCHANGE_HttpResponse *hr, const struct TALER_EXCHANGE_HttpResponse *hr,
const struct GNUNET_TIME_Absolute exchange_timestamp,
const struct TALER_ExchangeSignatureP *exchange_sig, const struct TALER_ExchangeSignatureP *exchange_sig,
const struct TALER_ExchangePublicKeyP *exchange_pub) const struct TALER_ExchangePublicKeyP *exchange_pub)
{ {
@ -254,6 +261,7 @@ deposit_cb (void *cls,
if (MHD_HTTP_OK == hr->http_status) if (MHD_HTTP_OK == hr->http_status)
{ {
ds->deposit_succeeded = GNUNET_YES; ds->deposit_succeeded = GNUNET_YES;
ds->exchange_timestamp = exchange_timestamp;
ds->exchange_pub = *exchange_pub; ds->exchange_pub = *exchange_pub;
ds->exchange_sig = *exchange_sig; ds->exchange_sig = *exchange_sig;
} }
@ -305,7 +313,7 @@ deposit_run (void *cls,
ds->coin_index = ods->coin_index; ds->coin_index = ods->coin_index;
ds->wire_details = json_incref (ods->wire_details); ds->wire_details = json_incref (ods->wire_details);
ds->contract_terms = json_incref (ods->contract_terms); ds->contract_terms = json_incref (ods->contract_terms);
ds->timestamp = ods->timestamp; ds->wallet_timestamp = ods->wallet_timestamp;
ds->refund_deadline = ods->refund_deadline; ds->refund_deadline = ods->refund_deadline;
ds->amount = ods->amount; ds->amount = ods->amount;
ds->merchant_priv = ods->merchant_priv; ds->merchant_priv = ods->merchant_priv;
@ -379,7 +387,7 @@ deposit_run (void *cls,
} }
else else
{ {
ds->refund_deadline = ds->timestamp; ds->refund_deadline = ds->wallet_timestamp;
wire_deadline = GNUNET_TIME_relative_to_absolute wire_deadline = GNUNET_TIME_relative_to_absolute
(GNUNET_TIME_UNIT_ZERO); (GNUNET_TIME_UNIT_ZERO);
} }
@ -388,6 +396,7 @@ deposit_run (void *cls,
(void) GNUNET_TIME_round_abs (&wire_deadline); (void) GNUNET_TIME_round_abs (&wire_deadline);
// FIXME: This should be part of TALER_EXCHANGE_deposit()!
{ {
struct TALER_DepositRequestPS dr; struct TALER_DepositRequestPS dr;
@ -400,7 +409,7 @@ deposit_run (void *cls,
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_JSON_merchant_wire_signature_hash (ds->wire_details, TALER_JSON_merchant_wire_signature_hash (ds->wire_details,
&dr.h_wire)); &dr.h_wire));
dr.timestamp = GNUNET_TIME_absolute_hton (ds->timestamp); dr.wallet_timestamp = GNUNET_TIME_absolute_hton (ds->wallet_timestamp);
dr.refund_deadline = GNUNET_TIME_absolute_hton dr.refund_deadline = GNUNET_TIME_absolute_hton
(ds->refund_deadline); (ds->refund_deadline);
TALER_amount_hton (&dr.amount_with_fee, TALER_amount_hton (&dr.amount_with_fee,
@ -421,7 +430,7 @@ deposit_run (void *cls,
&coin_pub, &coin_pub,
denom_pub_sig, denom_pub_sig,
&denom_pub->key, &denom_pub->key,
ds->timestamp, ds->wallet_timestamp,
&merchant_pub, &merchant_pub,
ds->refund_deadline, ds->refund_deadline,
&coin_sig, &coin_sig,
@ -534,6 +543,8 @@ deposit_traits (void *cls,
&ds->merchant_priv), &ds->merchant_priv),
TALER_TESTING_make_trait_amount_obj (0, TALER_TESTING_make_trait_amount_obj (0,
&ds->amount), &ds->amount),
TALER_TESTING_make_trait_absolute_time (0,
&ds->exchange_timestamp),
TALER_TESTING_trait_end () TALER_TESTING_trait_end ()
}; };
@ -599,12 +610,12 @@ TALER_TESTING_cmd_deposit (const char *label,
label); label);
GNUNET_assert (0); GNUNET_assert (0);
} }
ds->timestamp = GNUNET_TIME_absolute_get (); ds->wallet_timestamp = GNUNET_TIME_absolute_get ();
(void) GNUNET_TIME_round_abs (&ds->timestamp); (void) GNUNET_TIME_round_abs (&ds->wallet_timestamp);
json_object_set_new (ds->contract_terms, json_object_set_new (ds->contract_terms,
"timestamp", "timestamp",
GNUNET_JSON_from_time_abs (ds->timestamp)); GNUNET_JSON_from_time_abs (ds->wallet_timestamp));
if (0 != refund_deadline.rel_value_us) if (0 != refund_deadline.rel_value_us)
{ {
ds->refund_deadline = GNUNET_TIME_relative_to_absolute (refund_deadline); ds->refund_deadline = GNUNET_TIME_relative_to_absolute (refund_deadline);
@ -687,12 +698,12 @@ TALER_TESTING_cmd_deposit_with_ref (const char *label,
label); label);
GNUNET_assert (0); GNUNET_assert (0);
} }
ds->timestamp = GNUNET_TIME_absolute_get (); ds->wallet_timestamp = GNUNET_TIME_absolute_get ();
(void) GNUNET_TIME_round_abs (&ds->timestamp); (void) GNUNET_TIME_round_abs (&ds->wallet_timestamp);
json_object_set_new (ds->contract_terms, json_object_set_new (ds->contract_terms,
"timestamp", "timestamp",
GNUNET_JSON_from_time_abs (ds->timestamp)); GNUNET_JSON_from_time_abs (ds->wallet_timestamp));
if (0 != refund_deadline.rel_value_us) if (0 != refund_deadline.rel_value_us)
{ {
ds->refund_deadline = GNUNET_TIME_relative_to_absolute (refund_deadline); ds->refund_deadline = GNUNET_TIME_relative_to_absolute (refund_deadline);

View File

@ -57,6 +57,11 @@ struct InsertDepositState
*/ */
struct GNUNET_TIME_Relative wire_deadline; struct GNUNET_TIME_Relative wire_deadline;
/**
* When did the exchange receive the deposit?
*/
struct GNUNET_TIME_Absolute exchange_timestamp;
/** /**
* Amount to deposit, inclusive of deposit fee. * Amount to deposit, inclusive of deposit fee.
*/ */
@ -210,6 +215,7 @@ insert_deposit_run (void *cls,
(GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
ids->dbc->plugin->insert_deposit (ids->dbc->plugin->cls, ids->dbc->plugin->insert_deposit (ids->dbc->plugin->cls,
ids->dbc->session, ids->dbc->session,
ids->exchange_timestamp,
&deposit)) || &deposit)) ||
(GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
ids->dbc->plugin->commit (ids->dbc->plugin->cls, ids->dbc->plugin->commit (ids->dbc->plugin->cls,
@ -275,6 +281,7 @@ insert_deposit_traits (void *cls,
* @param dbc collects database plugin and session handles. * @param dbc collects database plugin and session handles.
* @param merchant_name Human-readable name of the merchant. * @param merchant_name Human-readable name of the merchant.
* @param merchant_account merchant's account name (NOT a payto:// URI) * @param merchant_account merchant's account name (NOT a payto:// URI)
* @param exchange_timestamp when did the exchange receive the deposit
* @param wire_deadline point in time where the aggregator should have * @param wire_deadline point in time where the aggregator should have
* wired money to the merchant. * wired money to the merchant.
* @param amount_with_fee amount to deposit (inclusive of deposit fee) * @param amount_with_fee amount to deposit (inclusive of deposit fee)
@ -282,21 +289,24 @@ insert_deposit_traits (void *cls,
* @return the command. * @return the command.
*/ */
struct TALER_TESTING_Command struct TALER_TESTING_Command
TALER_TESTING_cmd_insert_deposit (const char *label, TALER_TESTING_cmd_insert_deposit (
const struct const char *label,
TALER_TESTING_DatabaseConnection *dbc, const struct TALER_TESTING_DatabaseConnection *dbc,
const char *merchant_name, const char *merchant_name,
const char *merchant_account, const char *merchant_account,
struct GNUNET_TIME_Absolute exchange_timestamp,
struct GNUNET_TIME_Relative wire_deadline, struct GNUNET_TIME_Relative wire_deadline,
const char *amount_with_fee, const char *amount_with_fee,
const char *deposit_fee) const char *deposit_fee)
{ {
struct InsertDepositState *ids; struct InsertDepositState *ids;
GNUNET_TIME_round_abs (&exchange_timestamp);
ids = GNUNET_new (struct InsertDepositState); ids = GNUNET_new (struct InsertDepositState);
ids->dbc = dbc; ids->dbc = dbc;
ids->merchant_name = merchant_name; ids->merchant_name = merchant_name;
ids->merchant_account = merchant_account; ids->merchant_account = merchant_account;
ids->exchange_timestamp = exchange_timestamp;
ids->wire_deadline = wire_deadline; ids->wire_deadline = wire_deadline;
ids->amount_with_fee = amount_with_fee; ids->amount_with_fee = amount_with_fee;
ids->deposit_fee = deposit_fee; ids->deposit_fee = deposit_fee;