diff options
| author | Christian Grothoff <christian@grothoff.org> | 2020-05-07 20:22:02 +0200 | 
|---|---|---|
| committer | Christian Grothoff <christian@grothoff.org> | 2020-05-07 20:22:02 +0200 | 
| commit | 7ab9d526f23d52d87d47aa195351022db3748d2c (patch) | |
| tree | 2e0f9e4a077098a0babebb2b79530c189cbc8278 /src | |
| parent | af52541eacf5305977701fa24a530797994feb19 (diff) | |
towards changing timestamp in deposit confirmation (tests failing)
Diffstat (limited to 'src')
25 files changed, 390 insertions, 189 deletions
diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation.c b/src/auditor/taler-auditor-httpd_deposit-confirmation.c index 5f84a725..1039164c 100644 --- a/src/auditor/taler-auditor-httpd_deposit-confirmation.c +++ b/src/auditor/taler-auditor-httpd_deposit-confirmation.c @@ -155,7 +155,7 @@ verify_and_execute_deposit_confirmation (        .purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS)),        .h_contract_terms = dc->h_contract_terms,        .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),        .coin_pub = dc->coin_pub,        .merchant = dc->merchant @@ -224,7 +224,8 @@ TAH_DEPOSIT_CONFIRMATION_handler (struct TAH_RequestHandler *rh,    struct GNUNET_JSON_Specification spec[] = {      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_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),      TALER_JSON_spec_amount ("amount_without_fee", &dc.amount_without_fee),      GNUNET_JSON_spec_fixed_auto ("coin_pub", &dc.coin_pub), diff --git a/src/auditor/taler-helper-auditor-coins.c b/src/auditor/taler-helper-auditor-coins.c index 2e32c569..158baa8b 100644 --- a/src/auditor/taler-helper-auditor-coins.c +++ b/src/auditor/taler-helper-auditor-coins.c @@ -1535,7 +1535,8 @@ refresh_session_cb (void *cls,   *   * @param cls closure   * @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 denom_pub denomination public key of @a coin_pub   * @param coin_pub public key of the coin @@ -1553,7 +1554,8 @@ refresh_session_cb (void *cls,  static int  deposit_cb (void *cls,              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_DenominationPublicKey *denom_pub,              const struct TALER_CoinSpendPublicKeyP *coin_pub, @@ -1611,7 +1613,7 @@ deposit_cb (void *cls,        .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT),        .purpose.size = htonl (sizeof (dr)),        .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),        .deposit_fee = issue->fee_deposit,        .merchant = *merchant_pub, diff --git a/src/auditor/taler-helper-auditor-deposits.c b/src/auditor/taler-helper-auditor-deposits.c index 29155859..ed23c6a5 100644 --- a/src/auditor/taler-helper-auditor-deposits.c +++ b/src/auditor/taler-helper-auditor-deposits.c @@ -114,11 +114,15 @@ test_dc (void *cls,        .h_wire = dc->h_wire,        .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,                                        TALER_ARL_esession,                                        &dep, -                                      GNUNET_NO /* do not check refund deadline */); +                                      GNUNET_NO /* do not check refund deadline */, +                                      &deposit_fee, +                                      &exchange_timestamp);      if (qs > 0)      {        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -137,7 +141,8 @@ test_dc (void *cls,    TALER_ARL_report (report_deposit_confirmation_inconsistencies,                      json_pack ("{s:o, s:o, s:I, s:o}",                                 "timestamp", -                               TALER_ARL_json_from_time_abs (dc->timestamp), +                               TALER_ARL_json_from_time_abs ( +                                 dc->exchange_timestamp),                                 "amount",                                 TALER_JSON_from_amount (&dc->amount_without_fee),                                 "rowid", diff --git a/src/auditordb/auditor-0001.sql b/src/auditordb/auditor-0001.sql index ff8867be..b511a4d5 100644 --- a/src/auditordb/auditor-0001.sql +++ b/src/auditordb/auditor-0001.sql @@ -251,7 +251,7 @@ CREATE TABLE IF NOT EXISTS deposit_confirmations    ,serial_id BIGSERIAL UNIQUE    ,h_contract_terms BYTEA CHECK (LENGTH(h_contract_terms)=64)    ,h_wire BYTEA CHECK (LENGTH(h_wire)=64) -  ,timestamp INT8 NOT NULL +  ,exchange_timestamp INT8 NOT NULL    ,refund_deadline INT8 NOT NULL    ,amount_without_fee_val INT8 NOT NULL    ,amount_without_fee_frac INT4 NOT NULL diff --git a/src/auditordb/plugin_auditordb_postgres.c b/src/auditordb/plugin_auditordb_postgres.c index 467c4c6d..4f9101fd 100644 --- a/src/auditordb/plugin_auditordb_postgres.c +++ b/src/auditordb/plugin_auditordb_postgres.c @@ -269,7 +269,7 @@ postgres_get_session (void *cls)                              "(master_pub"                              ",h_contract_terms"                              ",h_wire" -                            ",timestamp" +                            ",exchange_timestamp"                              ",refund_deadline"                              ",amount_without_fee_val"                              ",amount_without_fee_frac" @@ -286,7 +286,7 @@ postgres_get_session (void *cls)                              " serial_id"                              ",h_contract_terms"                              ",h_wire" -                            ",timestamp" +                            ",exchange_timestamp"                              ",refund_deadline"                              ",amount_without_fee_val"                              ",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->h_contract_terms),      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_amount (&dc->amount_without_fee),      GNUNET_PQ_query_param_auto_from_type (&dc->coin_pub), @@ -1207,8 +1207,8 @@ deposit_confirmation_cb (void *cls,                                              &dc.h_contract_terms),        GNUNET_PQ_result_spec_auto_from_type ("h_wire",                                              &dc.h_wire), -      GNUNET_PQ_result_spec_absolute_time ("timestamp", -                                           &dc.timestamp), +      GNUNET_PQ_result_spec_absolute_time ("exchange_timestamp", +                                           &dc.exchange_timestamp),        GNUNET_PQ_result_spec_absolute_time ("refund_deadline",                                             &dc.refund_deadline),        TALER_PQ_RESULT_SPEC_AMOUNT ("amount_without_fee", diff --git a/src/exchange/taler-exchange-aggregator.c b/src/exchange/taler-exchange-aggregator.c index 21a29e50..69c73746 100644 --- a/src/exchange/taler-exchange-aggregator.c +++ b/src/exchange/taler-exchange-aggregator.c @@ -330,6 +330,8 @@ refund_by_coin_cb (void *cls,   *   * @param cls a `struct AggregationUnit`   * @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 coin_pub public key of the coin   * @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  deposit_cb (void *cls,              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_CoinSpendPublicKeyP *coin_pub,              const struct TALER_Amount *amount_with_fee, @@ -358,6 +362,8 @@ deposit_cb (void *cls,    /* NOTE: potential optimization: use custom SQL API to not       fetch this one: */    (void) wire_deadline; /* already checked by SQL query */ +  (void) exchange_timestamp; +  (void) wallet_timestamp;    au->merchant_pub = *merchant_pub;    GNUNET_log (GNUNET_ERROR_TYPE_INFO,                "Aggregator processing payment %s with amount %s\n", @@ -501,6 +507,8 @@ deposit_cb (void *cls,   *   * @param cls a `struct AggregationUnit`   * @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 coin_pub public key of the coin   * @param amount_with_fee amount that was deposited including fee @@ -514,6 +522,8 @@ deposit_cb (void *cls,  static enum GNUNET_DB_QueryStatus  aggregate_cb (void *cls,                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_CoinSpendPublicKeyP *coin_pub,                const struct TALER_Amount *amount_with_fee, @@ -529,6 +539,8 @@ aggregate_cb (void *cls,    /* NOTE: potential optimization: use custom SQL API to not       fetch these: */    (void) wire_deadline; /* checked by SQL */ +  (void) exchange_timestamp; +  (void) wallet_timestamp;    (void) wire; /* must match */    GNUNET_break (0 == GNUNET_memcmp (&au->merchant_pub,                                      merchant_pub)); diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c index 65251863..fe8fdf06 100644 --- a/src/exchange/taler-exchange-httpd_deposit.c +++ b/src/exchange/taler-exchange-httpd_deposit.c @@ -47,7 +47,7 @@   * @param coin_pub public key of the coin   * @param h_wire hash of wire 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 merchant merchant public key   * @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 GNUNET_HashCode *h_wire,                         const struct GNUNET_HashCode *h_contract_terms, -                       struct GNUNET_TIME_Absolute timestamp, +                       struct GNUNET_TIME_Absolute exchange_timestamp,                         struct GNUNET_TIME_Absolute refund_deadline,                         const struct TALER_MerchantPublicKeyP *merchant,                         const struct TALER_Amount *amount_without_fee) @@ -70,7 +70,7 @@ reply_deposit_success (struct MHD_Connection *connection,      .purpose.size = htonl (sizeof (dc)),      .h_contract_terms = *h_contract_terms,      .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),      .coin_pub = *coin_pub,      .merchant = *merchant @@ -88,13 +88,16 @@ reply_deposit_success (struct MHD_Connection *connection,                                         TALER_EC_EXCHANGE_BAD_CONFIGURATION,                                         "no keys");    } -  return TALER_MHD_reply_json_pack (connection, -                                    MHD_HTTP_OK, -                                    "{s:o, s:o}", -                                    "exchange_sig", -                                    GNUNET_JSON_from_data_auto (&sig), -                                    "exchange_pub", -                                    GNUNET_JSON_from_data_auto (&pub)); +  return TALER_MHD_reply_json_pack ( +    connection, +    MHD_HTTP_OK, +    "{s:o, s:o, s:o}", +    "exchange_timestamp", +    GNUNET_JSON_from_time_abs (exchange_timestamp), +    "exchange_sig", +    GNUNET_JSON_from_data_auto (&sig), +    "exchange_pub", +    GNUNET_JSON_from_data_auto (&pub));  } @@ -109,6 +112,11 @@ struct DepositContext    const struct TALER_EXCHANGEDB_Deposit *deposit;    /** +   * Our timestamp (when we received the request). +   */ +  struct GNUNET_TIME_Absolute exchange_timestamp; + +  /**     * Value of the coin.     */    struct TALER_Amount value; @@ -117,12 +125,11 @@ struct DepositContext  /** - * Execute database transaction for /deposit.  Runs the transaction - * logic; 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.  IF - * it returns the soft error code, the function MAY be called again to - * retry and MUST not queue a MHD response. + * 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 @@ -131,20 +138,22 @@ struct DepositContext   * @return transaction status   */  static enum GNUNET_DB_QueryStatus -deposit_transaction (void *cls, -                     struct MHD_Connection *connection, -                     struct TALER_EXCHANGEDB_Session *session, -                     MHD_RESULT *mhd_ret) +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 spent; +  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 */); +                                 GNUNET_YES /* check refund deadline */, +                                 &deposit_fee, +                                 &dc->exchange_timestamp);    if (qs < 0)    {      if (GNUNET_DB_STATUS_HARD_ERROR == qs) @@ -166,12 +175,12 @@ deposit_transaction (void *cls,      GNUNET_assert (0 <=                     TALER_amount_subtract (&amount_without_fee,                                            &deposit->amount_with_fee, -                                          &deposit->deposit_fee)); +                                          &deposit_fee));      *mhd_ret = reply_deposit_success (connection,                                        &deposit->coin.coin_pub,                                        &deposit->h_wire,                                        &deposit->h_contract_terms, -                                      deposit->timestamp, +                                      dc->exchange_timestamp,                                        deposit->refund_deadline,                                        &deposit->merchant_pub,                                        &amount_without_fee); @@ -179,6 +188,44 @@ deposit_transaction (void *cls,         never try again. */      return GNUNET_DB_STATUS_HARD_ERROR;    } +  return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; +} + + +/** + * Execute database transaction for /deposit.  Runs the transaction + * logic; 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.  IF + * it returns the soft error code, the function MAY be called again to + * retry and MUST not queue a MHD 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_transaction (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 spent; +  enum GNUNET_DB_QueryStatus qs; + +  /* 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, +                         mhd_ret); +  if (qs < 0) +    return qs;    /* Start with fee for THIS transaction */    spent = deposit->amount_with_fee; @@ -238,6 +285,7 @@ deposit_transaction (void *cls,    }    qs = TEH_plugin->insert_deposit (TEH_plugin->cls,                                     session, +                                   dc->exchange_timestamp,                                     deposit);    if (GNUNET_DB_STATUS_HARD_ERROR == qs)    { @@ -252,45 +300,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   * successful, passes the JSON data to #deposit_transaction() to   * further check the details of the operation specified.  If everything checks @@ -367,17 +376,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,                                         TALER_EC_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_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 !=        TALER_JSON_merchant_wire_signature_hash (wire,                                                 &my_h_wire)) @@ -401,6 +399,26 @@ TEH_handler_deposit (struct MHD_Connection *connection,                                         "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 */    {      struct TEH_KS_StateHandle *key_state; @@ -408,7 +426,7 @@ TEH_handler_deposit (struct MHD_Connection *connection,      enum TALER_ErrorCode ec;      unsigned int hc; -    key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ()); +    key_state = TEH_KS_acquire (dc.exchange_timestamp);      if (NULL == key_state)      {        TALER_LOG_ERROR ("Lacking keys to operate\n"); @@ -502,7 +520,7 @@ TEH_handler_deposit (struct MHD_Connection *connection,        .purpose.size = htonl (sizeof (dr)),        .h_contract_terms = deposit.h_contract_terms,        .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),        .merchant = deposit.merchant_pub,        .coin_pub = deposit.coin.coin_pub @@ -528,7 +546,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,    }    /* execute transaction */ -  dc.deposit = &deposit;    {      MHD_RESULT mhd_ret; @@ -557,7 +574,7 @@ TEH_handler_deposit (struct MHD_Connection *connection,                                   &deposit.coin.coin_pub,                                   &deposit.h_wire,                                   &deposit.h_contract_terms, -                                 deposit.timestamp, +                                 dc.exchange_timestamp,                                   deposit.refund_deadline,                                   &deposit.merchant_pub,                                   &amount_without_fee); diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c index 7924ad54..f6595161 100644 --- a/src/exchange/taler-exchange-httpd_responses.c +++ b/src/exchange/taler-exchange-httpd_responses.c @@ -66,7 +66,7 @@ TEH_RESPONSE_compile_transaction_history (            .purpose.size = htonl (sizeof (dr)),            .h_contract_terms = deposit->h_contract_terms,            .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),            .merchant = deposit->merchant_pub, diff --git a/src/exchangedb/exchange-0001.sql b/src/exchangedb/exchange-0001.sql index bec9af5b..ad05e779 100644 --- a/src/exchangedb/exchange-0001.sql +++ b/src/exchangedb/exchange-0001.sql @@ -254,7 +254,8 @@ CREATE TABLE IF NOT EXISTS deposits    ,coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub) ON DELETE CASCADE    ,amount_with_fee_val INT8 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    ,wire_deadline INT8 NOT NULL    ,merchant_pub BYTEA NOT NULL CHECK (LENGTH(merchant_pub)=32) diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index 5bd674b2..93577feb 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -796,7 +796,7 @@ postgres_get_session (void *cls)                                "(coin_pub"                                ",amount_with_fee_val"                                ",amount_with_fee_frac" -                              ",timestamp" +                              ",wallet_timestamp"                                ",refund_deadline"                                ",wire_deadline"                                ",merchant_pub" @@ -804,22 +804,28 @@ postgres_get_session (void *cls)                                ",h_wire"                                ",coin_sig"                                ",wire" +                              ",exchange_timestamp"                                ") VALUES "                                "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10," -                              " $11);", -                              11), +                              " $11, $12);", +                              12),        /* Fetch an existing deposit request, used to ensure idempotency           during /deposit processing. Used in #postgres_have_deposit(). */        GNUNET_PQ_make_prepare ("get_deposit",                                "SELECT"                                " amount_with_fee_val"                                ",amount_with_fee_frac" -                              ",timestamp" +                              ",denominations.fee_deposit_val" +                              ",denominations.fee_deposit_frac" +                              ",wallet_timestamp" +                              ",exchange_timestamp"                                ",refund_deadline"                                ",wire_deadline"                                ",h_contract_terms"                                ",h_wire"                                " FROM deposits" +                              " JOIN known_coins USING (coin_pub)" +                              " JOIN denominations USING (denom_pub_hash)"                                " WHERE ((coin_pub=$1)"                                "    AND (merchant_pub=$3)"                                "    AND (h_contract_terms=$2))" @@ -830,7 +836,8 @@ postgres_get_session (void *cls)                                "SELECT"                                " amount_with_fee_val"                                ",amount_with_fee_frac" -                              ",timestamp" +                              ",wallet_timestamp" +                              ",exchange_timestamp"                                ",merchant_pub"                                ",denom.denom_pub"                                ",coin_pub" @@ -881,6 +888,8 @@ postgres_get_session (void *cls)                                ",wire"                                ",merchant_pub"                                ",coin_pub" +                              ",exchange_timestamp" +                              ",wallet_timestamp"                                " FROM deposits"                                "    JOIN known_coins USING (coin_pub)"                                "    JOIN denominations denom USING (denom_pub_hash)" @@ -900,6 +909,8 @@ postgres_get_session (void *cls)                                ",denom.fee_deposit_val"                                ",denom.fee_deposit_frac"                                ",wire_deadline" +                              ",exchange_timestamp" +                              ",wallet_timestamp"                                ",h_contract_terms"                                ",coin_pub"                                " FROM deposits" @@ -945,7 +956,7 @@ postgres_get_session (void *cls)                                ",amount_with_fee_frac"                                ",denom.fee_deposit_val"                                ",denom.fee_deposit_frac" -                              ",timestamp" +                              ",wallet_timestamp"                                ",refund_deadline"                                ",wire_deadline"                                ",merchant_pub" @@ -2571,6 +2582,8 @@ postgres_get_reserve_history (void *cls,   * @param session database connection   * @param deposit deposit to search for   * @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,   *         0 if this exact deposit is unknown to us,   *         otherwise transaction error status @@ -2579,7 +2592,9 @@ static enum GNUNET_DB_QueryStatus  postgres_have_deposit (void *cls,                         struct TALER_EXCHANGEDB_Session *session,                         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 GNUNET_PQ_QueryParam params[] = { @@ -2592,12 +2607,16 @@ postgres_have_deposit (void *cls,    struct GNUNET_PQ_ResultSpec rs[] = {      TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",                                   &deposit2.amount_with_fee), -    TALER_PQ_result_spec_absolute_time ("timestamp", +    TALER_PQ_result_spec_absolute_time ("wallet_timestamp",                                          &deposit2.timestamp), +    TALER_PQ_result_spec_absolute_time ("exchange_timestamp", +                                        exchange_timestamp),      TALER_PQ_result_spec_absolute_time ("refund_deadline",                                          &deposit2.refund_deadline),      TALER_PQ_result_spec_absolute_time ("wire_deadline",                                          &deposit2.wire_deadline), +    TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit", +                                 deposit_fee),      GNUNET_PQ_result_spec_auto_from_type ("h_wire",                                            &deposit2.h_wire),      GNUNET_PQ_result_spec_end @@ -2776,6 +2795,8 @@ postgres_get_ready_deposit (void *cls,    struct TALER_Amount amount_with_fee;    struct TALER_Amount deposit_fee;    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 TALER_MerchantPublicKeyP merchant_pub;    struct TALER_CoinSpendPublicKeyP coin_pub; @@ -2788,6 +2809,10 @@ postgres_get_ready_deposit (void *cls,                                   &amount_with_fee),      TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit",                                   &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",                                          &wire_deadline),      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,                     serial_id, +                   exchange_timestamp, +                   wallet_timestamp,                     &merchant_pub,                     &coin_pub,                     &amount_with_fee, @@ -2898,6 +2925,8 @@ match_deposit_cb (void *cls,    {      struct TALER_Amount amount_with_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_HashCode h_contract_terms;      struct TALER_CoinSpendPublicKeyP coin_pub; @@ -2912,6 +2941,10 @@ match_deposit_cb (void *cls,                                     &deposit_fee),        TALER_PQ_result_spec_absolute_time ("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",                                              &h_contract_terms),        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,                            serial_id, +                          exchange_timestamp, +                          wallet_timestamp,                            mdc->merchant_pub,                            &coin_pub,                            &amount_with_fee, @@ -3210,12 +3245,14 @@ postgres_ensure_coin_known (void *cls,   *   * @param cls the `struct PostgresClosure` with the plugin-specific state   * @param session connection to the database + * @param exchange_timestamp time the exchange received the deposit request   * @param deposit deposit information to store   * @return query result status   */  static enum GNUNET_DB_QueryStatus  postgres_insert_deposit (void *cls,                           struct TALER_EXCHANGEDB_Session *session, +                         struct GNUNET_TIME_Absolute exchange_timestamp,                           const struct TALER_EXCHANGEDB_Deposit *deposit)  {    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->csig),      TALER_PQ_query_param_json (deposit->receiver_wire_account), +    TALER_PQ_query_param_absolute_time (&exchange_timestamp),      GNUNET_PQ_query_param_end    }; @@ -4042,7 +4080,7 @@ add_coin_deposit (void *cls,                                       &deposit->amount_with_fee),          TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit",                                       &deposit->deposit_fee), -        TALER_PQ_result_spec_absolute_time ("timestamp", +        TALER_PQ_result_spec_absolute_time ("wallet_timestamp",                                              &deposit->timestamp),          TALER_PQ_result_spec_absolute_time ("refund_deadline",                                              &deposit->refund_deadline), @@ -5462,14 +5500,17 @@ deposit_serial_helper_cb (void *cls,    for (unsigned int i = 0; i<num_results; i++)    {      struct TALER_EXCHANGEDB_Deposit deposit; +    struct GNUNET_TIME_Absolute exchange_timestamp;      struct TALER_DenominationPublicKey denom_pub;      uint8_t done = 0;      uint64_t rowid;      struct GNUNET_PQ_ResultSpec rs[] = {        TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",                                     &deposit.amount_with_fee), -      TALER_PQ_result_spec_absolute_time ("timestamp", +      TALER_PQ_result_spec_absolute_time ("wallet_timestamp",                                            &deposit.timestamp), +      TALER_PQ_result_spec_absolute_time ("exchange_timestamp", +                                          &exchange_timestamp),        GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",                                              &deposit.merchant_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,                     rowid, +                   exchange_timestamp,                     deposit.timestamp,                     &deposit.merchant_pub,                     &denom_pub, diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c index eea484e9..fe3ed785 100644 --- a/src/exchangedb/test_exchangedb.c +++ b/src/exchangedb/test_exchangedb.c @@ -833,6 +833,8 @@ static uint64_t deposit_rowid;   * @param cls closure a `struct TALER_EXCHANGEDB_Deposit *`   * @param rowid unique ID for the deposit in our DB, used for marking   *              it as 'tiny' or 'done' + * @param 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 coin_pub public key of the coin   * @param amount_with_fee amount that was deposited including fee @@ -846,6 +848,8 @@ static uint64_t deposit_rowid;  static enum GNUNET_DB_QueryStatus  deposit_cb (void *cls,              uint64_t rowid, +            struct GNUNET_TIME_Absolute exchange_timestamp, +            struct GNUNET_TIME_Absolute wallet_timestamp,              const struct TALER_MerchantPublicKeyP *merchant_pub,              const struct TALER_CoinSpendPublicKeyP *coin_pub,              const struct TALER_Amount *amount_with_fee, @@ -890,7 +894,8 @@ deposit_cb (void *cls,   *   * @param cls closure   * @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 denom_pub denomination of the @a coin_pub   * @param coin_pub public key of the coin @@ -908,7 +913,8 @@ deposit_cb (void *cls,  static int  audit_deposit_cb (void *cls,                    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_DenominationPublicKey *denom_pub,                    const struct TALER_CoinSpendPublicKeyP *coin_pub, @@ -1878,15 +1884,27 @@ run (void *cls)            plugin->ensure_coin_known (plugin->cls,                                       session,                                       &deposit.coin)); -  FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != -          plugin->insert_deposit (plugin->cls, +  { +    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 != +            plugin->insert_deposit (plugin->cls, +                                    session, +                                    now, +                                    &deposit)); +    FAILIF (1 != +            plugin->have_deposit (plugin->cls,                                    session, -                                  &deposit)); -  FAILIF (1 != -          plugin->have_deposit (plugin->cls, -                                session, -                                &deposit, -                                GNUNET_YES)); +                                  &deposit, +                                  GNUNET_YES, +                                  &deposit_fee, +                                  &r)); +    FAILIF (now.abs_value_us != r.abs_value_us); +  }    {      struct GNUNET_TIME_Absolute start_range;      struct GNUNET_TIME_Absolute end_range; @@ -1983,18 +2001,27 @@ run (void *cls)                           session,                           "test-2"));    RND_BLK (&deposit2.merchant_pub); /* should fail if merchant is different */ -  FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != -          plugin->have_deposit (plugin->cls, -                                session, -                                &deposit2, -                                GNUNET_YES)); -  deposit2.merchant_pub = deposit.merchant_pub; -  RND_BLK (&deposit2.coin.coin_pub); /* should fail if coin is different */ -  FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != -          plugin->have_deposit (plugin->cls, -                                session, -                                &deposit2, -                                GNUNET_YES)); +  { +    struct GNUNET_TIME_Absolute r; +    struct TALER_Amount deposit_fee; + +    FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != +            plugin->have_deposit (plugin->cls, +                                  session, +                                  &deposit2, +                                  GNUNET_YES, +                                  &deposit_fee, +                                  &r)); +    deposit2.merchant_pub = deposit.merchant_pub; +    RND_BLK (&deposit2.coin.coin_pub); /* should fail if coin is different */ +    FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != +            plugin->have_deposit (plugin->cls, +                                  session, +                                  &deposit2, +                                  GNUNET_YES, +                                  &deposit_fee, +                                  &r)); +  }    FAILIF (GNUNET_OK !=            test_melting (session));    FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != diff --git a/src/include/taler_auditordb_plugin.h b/src/include/taler_auditordb_plugin.h index 9a7f6ed7..7c58e654 100644 --- a/src/include/taler_auditordb_plugin.h +++ b/src/include/taler_auditordb_plugin.h @@ -300,9 +300,9 @@ struct TALER_AUDITORDB_DepositConfirmation    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 diff --git a/src/include/taler_error_codes.h b/src/include/taler_error_codes.h index 74660303..eded2333 100644 --- a/src/include/taler_error_codes.h +++ b/src/include/taler_error_codes.h @@ -1542,73 +1542,92 @@ enum TALER_ErrorCode     * This response is provided with HTTP status code     * #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     * for the /track/transfer request.  This response is provided with     * 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     * database. The response is provided with HTTP status code     * #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     * response is provided with HTTP status code     * #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     * database. The response is provided with HTTP status code     * #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     * 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.     * The response is provided with HTTP status code     * #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     * 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     * been wire transferred. The response is provided with HTTP status     * 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.     */ -  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 -   * advertised, and it is higher.  The response is provied with an HTTP -   * status of #MHD_HTTP_FAILED_DEPENDENCY. +   * advertised, and it is higher.  The response is provided with an +   * 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 diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index 82b9b83d..38928dc1 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -756,6 +756,7 @@ struct TALER_EXCHANGE_DepositHandle;   *   * @param cls closure   * @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_pub exchange key used to sign @a obj, or NULL   */ @@ -763,6 +764,7 @@ typedef void  (*TALER_EXCHANGE_DepositResultCallback) (    void *cls,    const struct TALER_EXCHANGE_HttpResponse *hr, +  struct GNUNET_TIME_Absolute deposit_timestamp,    const struct TALER_ExchangeSignatureP *exchange_sig,    const struct TALER_ExchangePublicKeyP *exchange_pub); diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index 4fd58072..9fb93236 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -975,6 +975,8 @@ struct TALER_EXCHANGEDB_Session;   * @param cls closure   * @param rowid unique ID for the deposit in our DB, used for marking   *              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 coin_pub public key of the coin   * @param amount_with_fee amount that was deposited including fee @@ -990,6 +992,8 @@ typedef enum GNUNET_DB_QueryStatus  (*TALER_EXCHANGEDB_DepositIterator)(    void *cls,    uint64_t rowid, +  struct GNUNET_TIME_Absolute exchange_timestamp, +  struct GNUNET_TIME_Absolute wallet_timestamp,    const struct TALER_MerchantPublicKeyP *merchant_pub,    const struct TALER_CoinSpendPublicKeyP *coin_pub,    const struct TALER_Amount *amount_with_fee, @@ -1022,7 +1026,8 @@ typedef void   *   * @param cls closure   * @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 denom_pub denomination public key of @a coin_pub   * @param coin_pub public key of the coin @@ -1042,7 +1047,8 @@ typedef int  (*TALER_EXCHANGEDB_DepositCallback)(    void *cls,    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_DenominationPublicKey *denom_pub,    const struct TALER_CoinSpendPublicKeyP *coin_pub, @@ -1841,6 +1847,8 @@ struct TALER_EXCHANGEDB_Plugin     * @param session database connection     * @param deposit deposit to search for     * @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,     *         0 if this exact deposit is unknown to us,     *         otherwise transaction error status @@ -1849,7 +1857,9 @@ struct TALER_EXCHANGEDB_Plugin    (*have_deposit)(void *cls,                    struct TALER_EXCHANGEDB_Session *session,                    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 session connection to the database +   * @param exchange_timestamp time the exchange received the deposit request     * @param deposit deposit information to store     * @return query result status     */    enum GNUNET_DB_QueryStatus    (*insert_deposit)(void *cls,                      struct TALER_EXCHANGEDB_Session *session, +                    struct GNUNET_TIME_Absolute exchange_timestamp,                      const struct TALER_EXCHANGEDB_Deposit *deposit); diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h index c346a6ce..38b895d7 100644 --- a/src/include/taler_signatures.h +++ b/src/include/taler_signatures.h @@ -363,7 +363,7 @@ struct TALER_DepositRequestPS     * deposit request in a timely fashion (so back-dating is not     * prevented).     */ -  struct GNUNET_TIME_AbsoluteNBO timestamp; +  struct GNUNET_TIME_AbsoluteNBO wallet_timestamp;    /**     * 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;    /** -   * 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 diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h index acc218ac..6a4fa024 100644 --- a/src/include/taler_testing_lib.h +++ b/src/include/taler_testing_lib.h @@ -1903,6 +1903,7 @@ TALER_TESTING_cmd_connect_with_state (const char *label,   * @param dbc collects plugin and session handles   * @param merchant_name Human-readable name of the merchant.   * @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   *        wired money to the merchant.   * @param amount_with_fee amount to deposit (inclusive of deposit fee) @@ -1910,14 +1911,15 @@ TALER_TESTING_cmd_connect_with_state (const char *label,   * @return the command.   */  struct TALER_TESTING_Command -TALER_TESTING_cmd_insert_deposit (const char *label, -                                  const struct -                                  TALER_TESTING_DatabaseConnection *dbc, -                                  const char *merchant_name, -                                  const char *merchant_account, -                                  struct GNUNET_TIME_Relative wire_deadline, -                                  const char *amount_with_fee, -                                  const char *deposit_fee); +TALER_TESTING_cmd_insert_deposit ( +  const char *label, +  const struct TALER_TESTING_DatabaseConnection *dbc, +  const char *merchant_name, +  const char *merchant_account, +  struct GNUNET_TIME_Absolute exchange_timestamp, +  struct GNUNET_TIME_Relative wire_deadline, +  const char *amount_with_fee, +  const char *deposit_fee);  /** diff --git a/src/lib/auditor_api_deposit_confirmation.c b/src/lib/auditor_api_deposit_confirmation.c index cddfe8b1..1856a89f 100644 --- a/src/lib/auditor_api_deposit_confirmation.c +++ b/src/lib/auditor_api_deposit_confirmation.c @@ -148,7 +148,7 @@ handle_deposit_confirmation_finished (void *cls,   *   * @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 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 amount_without_fee the amount confirmed to be wired by the exchange to the merchant   * @param coin_pub coin’s public key @@ -165,7 +165,7 @@ handle_deposit_confirmation_finished (void *cls,  static int  verify_signatures (const struct GNUNET_HashCode *h_wire,                     const struct GNUNET_HashCode *h_contract_terms, -                   struct GNUNET_TIME_Absolute timestamp, +                   struct GNUNET_TIME_Absolute exchange_timestamp,                     struct GNUNET_TIME_Absolute refund_deadline,                     const struct TALER_Amount *amount_without_fee,                     const struct TALER_CoinSpendPublicKeyP *coin_pub, @@ -184,7 +184,7 @@ verify_signatures (const struct GNUNET_HashCode *h_wire,        .purpose.size = htonl (sizeof (dc)),        .h_contract_terms = *h_contract_terms,        .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),        .coin_pub = *coin_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 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 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 amount_without_fee the amount confirmed to be wired by the exchange to the merchant   * @param coin_pub coin’s public key @@ -278,7 +278,7 @@ TALER_AUDITOR_deposit_confirmation (    struct TALER_AUDITOR_Handle *auditor,    const struct GNUNET_HashCode *h_wire,    const struct GNUNET_HashCode *h_contract_terms, -  struct GNUNET_TIME_Absolute timestamp, +  struct GNUNET_TIME_Absolute exchange_timestamp,    struct GNUNET_TIME_Absolute refund_deadline,    const struct TALER_Amount *amount_without_fee,    const struct TALER_CoinSpendPublicKeyP *coin_pub, @@ -298,7 +298,7 @@ TALER_AUDITOR_deposit_confirmation (    json_t *deposit_confirmation_obj;    CURL *eh; -  (void) GNUNET_TIME_round_abs (×tamp); +  (void) GNUNET_TIME_round_abs (&exchange_timestamp);    (void) GNUNET_TIME_round_abs (&refund_deadline);    (void) GNUNET_TIME_round_abs (&ep_start);    (void) GNUNET_TIME_round_abs (&ep_expire); @@ -308,7 +308,7 @@ TALER_AUDITOR_deposit_confirmation (    if (GNUNET_OK !=        verify_signatures (h_wire,                           h_contract_terms, -                         timestamp, +                         exchange_timestamp,                           refund_deadline,                           amount_without_fee,                           coin_pub, @@ -336,7 +336,8 @@ TALER_AUDITOR_deposit_confirmation (                   "h_wire", GNUNET_JSON_from_data_auto (h_wire),                   "h_contract_terms", GNUNET_JSON_from_data_auto (                     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),                   "amount_without_fee", TALER_JSON_from_amount (                     amount_without_fee), diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c index dc44291d..bf8eb537 100644 --- a/src/lib/exchange_api_common.c +++ b/src/lib/exchange_api_common.c @@ -524,7 +524,7 @@ TALER_EXCHANGE_verify_coin_history (          GNUNET_JSON_spec_fixed_auto ("h_wire",                                       &dr.h_wire),          GNUNET_JSON_spec_absolute_time_nbo ("timestamp", -                                            &dr.timestamp), +                                            &dr.wallet_timestamp),          GNUNET_JSON_spec_absolute_time_nbo ("refund_deadline",                                              &dr.refund_deadline),          TALER_JSON_spec_amount_nbo ("deposit_fee", diff --git a/src/lib/exchange_api_deposit.c b/src/lib/exchange_api_deposit.c index a5cf6c36..27605365 100644 --- a/src/lib/exchange_api_deposit.c +++ b/src/lib/exchange_api_deposit.c @@ -160,7 +160,7 @@ auditor_cb (void *cls,      ah,      &dh->depconf.h_wire,      &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),      &amount_without_fee,      &dh->depconf.coin_pub, @@ -198,6 +198,8 @@ verify_deposit_signature_ok (struct TALER_EXCHANGE_DepositHandle *dh,    struct GNUNET_JSON_Specification spec[] = {      GNUNET_JSON_spec_fixed_auto ("exchange_sig", exchange_sig),      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 ()    }; @@ -386,6 +388,7 @@ handle_deposit_finished (void *cls,    }    dh->cb (dh->cb_cls,            &hr, +          GNUNET_TIME_absolute_ntoh (dh->depconf.exchange_timestamp),            es,            ep);    TALER_EXCHANGE_deposit_cancel (dh); @@ -429,7 +432,7 @@ verify_signatures (const struct TALER_EXCHANGE_DenomPublicKey *dki,        .purpose.size = htonl (sizeof (dr)),        .h_contract_terms = *h_contract_terms,        .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),        .merchant = *merchant_pub,        .coin_pub = *coin_pub @@ -658,7 +661,7 @@ TALER_EXCHANGE_deposit (struct TALER_EXCHANGE_Handle *exchange,      TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT);    dh->depconf.h_contract_terms = *h_contract_terms;    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);    TALER_amount_hton (&dh->depconf.amount_without_fee,                       &amount_without_fee); diff --git a/src/lib/exchange_api_refund.c b/src/lib/exchange_api_refund.c index b1ea176b..6f91389f 100644 --- a/src/lib/exchange_api_refund.c +++ b/src/lib/exchange_api_refund.c @@ -148,7 +148,8 @@ handle_refund_finished (void *cls,    struct TALER_ExchangeSignatureP exchange_sig;    struct TALER_ExchangePublicKeyP *ep = 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;    struct TALER_EXCHANGE_HttpResponse hr = {      .reply = j, @@ -176,7 +177,9 @@ handle_refund_finished (void *cls,      {        ep = &exchange_pub;        es = &exchange_sig; -      rf = &rh->depconf.refund_fee; +      TALER_amount_ntoh (&ra, +                         &rh->depconf.refund_fee); +      rf = &ra;      }      break;    case MHD_HTTP_BAD_REQUEST: diff --git a/src/testing/test_taler_exchange_aggregator.c b/src/testing/test_taler_exchange_aggregator.c index eaa621cf..d5c392d3 100644 --- a/src/testing/test_taler_exchange_aggregator.c +++ b/src/testing/test_taler_exchange_aggregator.c @@ -108,6 +108,7 @@ run (void *cls,                                        &dbc,                                        "bob",                                        USER42_ACCOUNT, +                                      GNUNET_TIME_absolute_get (),                                        GNUNET_TIME_UNIT_ZERO,                                        "EUR:1",                                        "EUR:0.1"), @@ -126,6 +127,7 @@ run (void *cls,                                        &dbc,                                        "bob",                                        USER42_ACCOUNT, +                                      GNUNET_TIME_absolute_get (),                                        GNUNET_TIME_UNIT_ZERO,                                        "EUR:1",                                        "EUR:0.1"), @@ -134,6 +136,7 @@ run (void *cls,                                        &dbc,                                        "bob",                                        USER42_ACCOUNT, +                                      GNUNET_TIME_absolute_get (),                                        GNUNET_TIME_UNIT_ZERO,                                        "EUR:1",                                        "EUR:0.1"), @@ -153,6 +156,7 @@ run (void *cls,                                        &dbc,                                        "bob",                                        "4", +                                      GNUNET_TIME_absolute_get (),                                        GNUNET_TIME_UNIT_ZERO,                                        "EUR:1",                                        "EUR:0.1"), @@ -160,6 +164,7 @@ run (void *cls,                                        &dbc,                                        "bob",                                        "5", +                                      GNUNET_TIME_absolute_get (),                                        GNUNET_TIME_UNIT_ZERO,                                        "EUR:1",                                        "EUR:0.1"), @@ -167,6 +172,7 @@ run (void *cls,                                        &dbc,                                        "alice",                                        "4", +                                      GNUNET_TIME_absolute_get (),                                        GNUNET_TIME_UNIT_ZERO,                                        "EUR:1",                                        "EUR:0.1"), @@ -195,6 +201,7 @@ run (void *cls,                                        &dbc,                                        "bob",                                        USER42_ACCOUNT, +                                      GNUNET_TIME_absolute_get (),                                        GNUNET_TIME_relative_multiply                                          (GNUNET_TIME_UNIT_SECONDS,                                          5), @@ -204,6 +211,7 @@ run (void *cls,                                        &dbc,                                        "bob",                                        USER42_ACCOUNT, +                                      GNUNET_TIME_absolute_get (),                                        GNUNET_TIME_relative_multiply                                          (GNUNET_TIME_UNIT_SECONDS,                                          5), @@ -229,6 +237,7 @@ run (void *cls,                                        &dbc,                                        "bob",                                        USER42_ACCOUNT, +                                      GNUNET_TIME_absolute_get (),                                        GNUNET_TIME_relative_multiply                                          (GNUNET_TIME_UNIT_SECONDS,                                          10), @@ -239,6 +248,7 @@ run (void *cls,                                        &dbc,                                        "bob",                                        USER42_ACCOUNT, +                                      GNUNET_TIME_absolute_get (),                                        GNUNET_TIME_relative_multiply                                          (GNUNET_TIME_UNIT_SECONDS,                                          5), @@ -263,6 +273,7 @@ run (void *cls,                                        &dbc,                                        "bob",                                        USER42_ACCOUNT, +                                      GNUNET_TIME_absolute_get (),                                        GNUNET_TIME_UNIT_ZERO,                                        "EUR:0.102",                                        "EUR:0.1"), @@ -274,6 +285,7 @@ run (void *cls,                                        &dbc,                                        "bob",                                        USER42_ACCOUNT, +                                      GNUNET_TIME_absolute_get (),                                        GNUNET_TIME_UNIT_ZERO,                                        "EUR:0.102",                                        "EUR:0.1"), @@ -281,6 +293,7 @@ run (void *cls,                                        &dbc,                                        "bob",                                        USER42_ACCOUNT, +                                      GNUNET_TIME_absolute_get (),                                        GNUNET_TIME_UNIT_ZERO,                                        "EUR:0.102",                                        "EUR:0.1"), @@ -292,6 +305,7 @@ run (void *cls,                                        &dbc,                                        "bob",                                        USER42_ACCOUNT, +                                      GNUNET_TIME_absolute_get (),                                        GNUNET_TIME_UNIT_ZERO,                                        "EUR:0.102",                                        "EUR:0.1"), @@ -303,6 +317,7 @@ run (void *cls,                                        &dbc,                                        "bob",                                        USER42_ACCOUNT, +                                      GNUNET_TIME_absolute_get (),                                        GNUNET_TIME_UNIT_ZERO,                                        "EUR:0.112",                                        "EUR:0.1"), @@ -319,6 +334,7 @@ run (void *cls,                                        &dbc,                                        "bob",                                        USER42_ACCOUNT, +                                      GNUNET_TIME_absolute_get (),                                        GNUNET_TIME_UNIT_ZERO,                                        "EUR:0.109",                                        "EUR:0.1"), @@ -330,6 +346,7 @@ run (void *cls,                                        &dbc,                                        "bob",                                        USER42_ACCOUNT, +                                      GNUNET_TIME_absolute_get (),                                        GNUNET_TIME_UNIT_ZERO,                                        "EUR:0.119",                                        "EUR:0.1"), @@ -346,6 +363,7 @@ run (void *cls,                                        &dbc,                                        "bob",                                        USER42_ACCOUNT, +                                      GNUNET_TIME_absolute_get (),                                        GNUNET_TIME_UNIT_ZERO,                                        "EUR:0.122",                                        "EUR:0.1"), @@ -362,6 +380,7 @@ run (void *cls,                                        &dbc,                                        "bob",                                        USER42_ACCOUNT, +                                      GNUNET_TIME_absolute_get (),                                        GNUNET_TIME_relative_multiply                                          (GNUNET_TIME_UNIT_SECONDS,                                          5), @@ -375,6 +394,7 @@ run (void *cls,                                        &dbc,                                        "bob",                                        USER42_ACCOUNT, +                                      GNUNET_TIME_absolute_get (),                                        GNUNET_TIME_relative_multiply                                          (GNUNET_TIME_UNIT_SECONDS,                                          5), @@ -390,6 +410,7 @@ run (void *cls,                                        &dbc,                                        "bob",                                        USER42_ACCOUNT, +                                      GNUNET_TIME_absolute_get (),                                        GNUNET_TIME_UNIT_ZERO,                                        "EUR:0.122",                                        "EUR:0.1"), @@ -406,6 +427,7 @@ run (void *cls,                                        &dbc,                                        "bob",                                        USER42_ACCOUNT, +                                      GNUNET_TIME_absolute_get (),                                        GNUNET_TIME_relative_multiply                                          (GNUNET_TIME_UNIT_SECONDS,                                          5), @@ -419,6 +441,7 @@ run (void *cls,                                        &dbc,                                        "bob",                                        USER42_ACCOUNT, +                                      GNUNET_TIME_absolute_get (),                                        GNUNET_TIME_relative_multiply                                          (GNUNET_TIME_UNIT_SECONDS,                                          5), @@ -434,6 +457,7 @@ run (void *cls,                                        &dbc,                                        "bob",                                        USER42_ACCOUNT, +                                      GNUNET_TIME_absolute_get (),                                        GNUNET_TIME_UNIT_ZERO,                                        "EUR:0.112",                                        "EUR:0.1"), diff --git a/src/testing/testing_api_cmd_auditor_deposit_confirmation.c b/src/testing/testing_api_cmd_auditor_deposit_confirmation.c index 247399a9..1442380b 100644 --- a/src/testing/testing_api_cmd_auditor_deposit_confirmation.c +++ b/src/testing/testing_api_cmd_auditor_deposit_confirmation.c @@ -203,6 +203,7 @@ deposit_confirmation_run (void *cls,    const struct TALER_TESTING_Command *deposit_cmd;    struct GNUNET_HashCode h_wire;    struct GNUNET_HashCode h_contract_terms; +  const struct GNUNET_TIME_Absolute *exchange_timestamp = NULL;    struct GNUNET_TIME_Absolute timestamp;    struct GNUNET_TIME_Absolute refund_deadline;    struct TALER_Amount amount_without_fee; @@ -238,6 +239,11 @@ deposit_confirmation_run (void *cls,                   TALER_TESTING_get_trait_exchange_sig (deposit_cmd,                                                         dcs->coin_index,                                                         &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);    GNUNET_assert (NULL != 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,                                                  &h_wire,                                                  &h_contract_terms, -                                                timestamp, +                                                *exchange_timestamp,                                                  refund_deadline,                                                  &amount_without_fee,                                                  &coin_pub, diff --git a/src/testing/testing_api_cmd_deposit.c b/src/testing/testing_api_cmd_deposit.c index 9468e7ac..049f36f2 100644 --- a/src/testing/testing_api_cmd_deposit.c +++ b/src/testing/testing_api_cmd_deposit.c @@ -91,9 +91,9 @@ struct DepositState    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. @@ -127,6 +127,11 @@ struct DepositState    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     * deposit confirmation.     */ @@ -198,6 +203,7 @@ do_retry (void *cls)   *   * @param cls closure.   * @param hr HTTP response details + * @param exchange_timestamp when did the exchange receive the deposit permission   * @param exchange_sig signature provided by the exchange   *        (NULL on errors)   * @param exchange_pub public key of the exchange, @@ -206,6 +212,7 @@ do_retry (void *cls)  static void  deposit_cb (void *cls,              const struct TALER_EXCHANGE_HttpResponse *hr, +            const struct GNUNET_TIME_Absolute exchange_timestamp,              const struct TALER_ExchangeSignatureP *exchange_sig,              const struct TALER_ExchangePublicKeyP *exchange_pub)  { @@ -254,6 +261,7 @@ deposit_cb (void *cls,    if (MHD_HTTP_OK == hr->http_status)    {      ds->deposit_succeeded = GNUNET_YES; +    ds->exchange_timestamp = exchange_timestamp;      ds->exchange_pub = *exchange_pub;      ds->exchange_sig = *exchange_sig;    } @@ -305,7 +313,7 @@ deposit_run (void *cls,      ds->coin_index = ods->coin_index;      ds->wire_details = json_incref (ods->wire_details);      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->amount = ods->amount;      ds->merchant_priv = ods->merchant_priv; @@ -379,7 +387,7 @@ deposit_run (void *cls,    }    else    { -    ds->refund_deadline = ds->timestamp; +    ds->refund_deadline = ds->wallet_timestamp;      wire_deadline = GNUNET_TIME_relative_to_absolute                        (GNUNET_TIME_UNIT_ZERO);    } @@ -388,6 +396,7 @@ deposit_run (void *cls,    (void) GNUNET_TIME_round_abs (&wire_deadline); +  // FIXME: This should be part of TALER_EXCHANGE_deposit()!    {      struct TALER_DepositRequestPS dr; @@ -400,7 +409,7 @@ deposit_run (void *cls,      GNUNET_assert (GNUNET_OK ==                     TALER_JSON_merchant_wire_signature_hash (ds->wire_details,                                                              &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                             (ds->refund_deadline);      TALER_amount_hton (&dr.amount_with_fee, @@ -421,7 +430,7 @@ deposit_run (void *cls,                                     &coin_pub,                                     denom_pub_sig,                                     &denom_pub->key, -                                   ds->timestamp, +                                   ds->wallet_timestamp,                                     &merchant_pub,                                     ds->refund_deadline,                                     &coin_sig, @@ -534,6 +543,8 @@ deposit_traits (void *cls,                                                &ds->merchant_priv),        TALER_TESTING_make_trait_amount_obj (0,                                             &ds->amount), +      TALER_TESTING_make_trait_absolute_time (0, +                                              &ds->exchange_timestamp),        TALER_TESTING_trait_end ()      }; @@ -599,12 +610,12 @@ TALER_TESTING_cmd_deposit (const char *label,                  label);      GNUNET_assert (0);    } -  ds->timestamp = GNUNET_TIME_absolute_get (); -  (void) GNUNET_TIME_round_abs (&ds->timestamp); +  ds->wallet_timestamp = GNUNET_TIME_absolute_get (); +  (void) GNUNET_TIME_round_abs (&ds->wallet_timestamp);    json_object_set_new (ds->contract_terms,                         "timestamp", -                       GNUNET_JSON_from_time_abs (ds->timestamp)); +                       GNUNET_JSON_from_time_abs (ds->wallet_timestamp));    if (0 != refund_deadline.rel_value_us)    {      ds->refund_deadline = GNUNET_TIME_relative_to_absolute (refund_deadline); @@ -687,12 +698,12 @@ TALER_TESTING_cmd_deposit_with_ref (const char *label,                  label);      GNUNET_assert (0);    } -  ds->timestamp = GNUNET_TIME_absolute_get (); -  (void) GNUNET_TIME_round_abs (&ds->timestamp); +  ds->wallet_timestamp = GNUNET_TIME_absolute_get (); +  (void) GNUNET_TIME_round_abs (&ds->wallet_timestamp);    json_object_set_new (ds->contract_terms,                         "timestamp", -                       GNUNET_JSON_from_time_abs (ds->timestamp)); +                       GNUNET_JSON_from_time_abs (ds->wallet_timestamp));    if (0 != refund_deadline.rel_value_us)    {      ds->refund_deadline = GNUNET_TIME_relative_to_absolute (refund_deadline); diff --git a/src/testing/testing_api_cmd_insert_deposit.c b/src/testing/testing_api_cmd_insert_deposit.c index 35652800..cff2884a 100644 --- a/src/testing/testing_api_cmd_insert_deposit.c +++ b/src/testing/testing_api_cmd_insert_deposit.c @@ -58,6 +58,11 @@ struct InsertDepositState    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.     */    const char *amount_with_fee; @@ -210,6 +215,7 @@ insert_deposit_run (void *cls,         (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=          ids->dbc->plugin->insert_deposit (ids->dbc->plugin->cls,                                            ids->dbc->session, +                                          ids->exchange_timestamp,                                            &deposit)) ||         (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=          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 merchant_name Human-readable name of the merchant.   * @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   *        wired money to the merchant.   * @param amount_with_fee amount to deposit (inclusive of deposit fee) @@ -282,21 +289,24 @@ insert_deposit_traits (void *cls,   * @return the command.   */  struct TALER_TESTING_Command -TALER_TESTING_cmd_insert_deposit (const char *label, -                                  const struct -                                  TALER_TESTING_DatabaseConnection *dbc, -                                  const char *merchant_name, -                                  const char *merchant_account, -                                  struct GNUNET_TIME_Relative wire_deadline, -                                  const char *amount_with_fee, -                                  const char *deposit_fee) +TALER_TESTING_cmd_insert_deposit ( +  const char *label, +  const struct TALER_TESTING_DatabaseConnection *dbc, +  const char *merchant_name, +  const char *merchant_account, +  struct GNUNET_TIME_Absolute exchange_timestamp, +  struct GNUNET_TIME_Relative wire_deadline, +  const char *amount_with_fee, +  const char *deposit_fee)  {    struct InsertDepositState *ids; +  GNUNET_TIME_round_abs (&exchange_timestamp);    ids = GNUNET_new (struct InsertDepositState);    ids->dbc = dbc;    ids->merchant_name = merchant_name;    ids->merchant_account = merchant_account; +  ids->exchange_timestamp = exchange_timestamp;    ids->wire_deadline = wire_deadline;    ids->amount_with_fee = amount_with_fee;    ids->deposit_fee = deposit_fee;  | 
