diff options
Diffstat (limited to 'src/exchangedb')
-rw-r--r-- | src/exchangedb/exchange-0001.sql | 3 | ||||
-rw-r--r-- | src/exchangedb/plugin_exchangedb_postgres.c | 62 | ||||
-rw-r--r-- | src/exchangedb/test_exchangedb.c | 71 |
3 files changed, 103 insertions, 33 deletions
diff --git a/src/exchangedb/exchange-0001.sql b/src/exchangedb/exchange-0001.sql index bec9af5ba..ad05e7797 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 5bd674b2d..93577feb4 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 eea484e94..fe3ed7854 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 != |