From 7ff58c3d8f2351c57142b4b65ab75304f355fc4f Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 5 Mar 2022 14:36:49 +0100 Subject: refactor /wire to include logic to return the wad fee (for W2W payments) --- src/exchangedb/exchange-0001.sql | 23 ++++ src/exchangedb/irbt_callbacks.c | 31 +++++- src/exchangedb/lrbt_callbacks.c | 58 +++++++++- src/exchangedb/plugin_exchangedb_postgres.c | 161 +++++++++++++--------------- src/exchangedb/test_exchangedb.c | 31 +++--- 5 files changed, 198 insertions(+), 106 deletions(-) (limited to 'src/exchangedb') diff --git a/src/exchangedb/exchange-0001.sql b/src/exchangedb/exchange-0001.sql index 3331eada2..a3996d120 100644 --- a/src/exchangedb/exchange-0001.sql +++ b/src/exchangedb/exchange-0001.sql @@ -835,6 +835,8 @@ CREATE TABLE IF NOT EXISTS wire_fee ,wire_fee_frac INT4 NOT NULL ,closing_fee_val INT8 NOT NULL ,closing_fee_frac INT4 NOT NULL + ,wad_fee_val INT8 NOT NULL + ,wad_fee_frac INT4 NOT NULL ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64) ,PRIMARY KEY (wire_method, start_date) ); @@ -848,6 +850,27 @@ CREATE INDEX IF NOT EXISTS wire_fee_by_end_date_index (end_date); +CREATE TABLE IF NOT EXISTS global_fee + (global_fee_serial BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE + ,start_date INT8 NOT NULL + ,end_date INT8 NOT NULL + ,history_fee_val INT8 NOT NULL + ,history_fee_frac INT4 NOT NULL + ,kyc_fee_val INT8 NOT NULL + ,kyc_fee_frac INT4 NOT NULL + ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64) + ,PRIMARY KEY (start_date) + ); +COMMENT ON TABLE global_fee + IS 'list of the global fees of this exchange, by date'; +COMMENT ON COLUMN global_fee.global_fee_serial + IS 'needed for exchange-auditor replication logic'; + +CREATE INDEX IF NOT EXISTS global_fee_by_end_date_index + ON global_fee + (end_date); + + CREATE TABLE IF NOT EXISTS recoup (recoup_uuid BIGINT GENERATED BY DEFAULT AS IDENTITY -- UNIQUE ,known_coin_id INT8 NOT NULL -- REFERENCES known_coins (known_coin_id) diff --git a/src/exchangedb/irbt_callbacks.c b/src/exchangedb/irbt_callbacks.c index deab3cfca..ae4863436 100644 --- a/src/exchangedb/irbt_callbacks.c +++ b/src/exchangedb/irbt_callbacks.c @@ -635,8 +635,9 @@ irbt_cb_table_wire_fee (struct PostgresClosure *pg, GNUNET_PQ_query_param_string (td->details.wire_fee.wire_method), GNUNET_PQ_query_param_timestamp (&td->details.wire_fee.start_date), GNUNET_PQ_query_param_timestamp (&td->details.wire_fee.end_date), - TALER_PQ_query_param_amount (&td->details.wire_fee.wire_fee), - TALER_PQ_query_param_amount (&td->details.wire_fee.closing_fee), + TALER_PQ_query_param_amount (&td->details.wire_fee.fees.wire), + TALER_PQ_query_param_amount (&td->details.wire_fee.fees.closing), + TALER_PQ_query_param_amount (&td->details.wire_fee.fees.wad), GNUNET_PQ_query_param_auto_from_type (&td->details.wire_fee.master_sig), GNUNET_PQ_query_param_end }; @@ -647,6 +648,32 @@ irbt_cb_table_wire_fee (struct PostgresClosure *pg, } +/** + * Function called with wire_fee records to insert into table. + * + * @param pg plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_global_fee (struct PostgresClosure *pg, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_timestamp (&td->details.global_fee.start_date), + GNUNET_PQ_query_param_timestamp (&td->details.global_fee.end_date), + TALER_PQ_query_param_amount (&td->details.global_fee.fees.history), + TALER_PQ_query_param_amount (&td->details.global_fee.fees.kyc), + GNUNET_PQ_query_param_auto_from_type (&td->details.wire_fee.master_sig), + GNUNET_PQ_query_param_end + }; + + return GNUNET_PQ_eval_prepared_non_select (pg->conn, + "insert_into_table_global_fee", + params); +} + + /** * Function called with recoup records to insert into table. * diff --git a/src/exchangedb/lrbt_callbacks.c b/src/exchangedb/lrbt_callbacks.c index 7f1d2fdb9..233ecbc1f 100644 --- a/src/exchangedb/lrbt_callbacks.c +++ b/src/exchangedb/lrbt_callbacks.c @@ -1173,9 +1173,11 @@ lrbt_cb_table_wire_fee (void *cls, GNUNET_PQ_result_spec_timestamp ("end_date", &td.details.wire_fee.end_date), TALER_PQ_RESULT_SPEC_AMOUNT ("wire_fee", - &td.details.wire_fee.wire_fee), + &td.details.wire_fee.fees.wire), TALER_PQ_RESULT_SPEC_AMOUNT ("closing_fee", - &td.details.wire_fee.closing_fee), + &td.details.wire_fee.fees.closing), + TALER_PQ_RESULT_SPEC_AMOUNT ("wad_fee", + &td.details.wire_fee.fees.wad), GNUNET_PQ_result_spec_auto_from_type ("master_sig", &td.details.wire_fee.master_sig), GNUNET_PQ_result_spec_end @@ -1197,6 +1199,58 @@ lrbt_cb_table_wire_fee (void *cls, } +/** + * Function called with wire_fee table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_global_fee (void *cls, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct PostgresClosure *pg = ctx->pg; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_GLOBAL_FEE + }; + + for (unsigned int i = 0; ierror = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + /** * Function called with recoup table entries. * diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index 9a3229f47..cdc383bf2 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -1347,6 +1347,8 @@ prepare_statements (struct PostgresClosure *pg) ",wire_fee_frac" ",closing_fee_val" ",closing_fee_frac" + ",wad_fee_val" + ",wad_fee_frac" ",master_sig" " FROM wire_fee" " WHERE wire_method=$1" @@ -1364,10 +1366,12 @@ prepare_statements (struct PostgresClosure *pg) ",wire_fee_frac" ",closing_fee_val" ",closing_fee_frac" + ",wad_fee_val" + ",wad_fee_frac" ",master_sig" ") VALUES " - "($1, $2, $3, $4, $5, $6, $7, $8);", - 8), + "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);", + 10), /* Used in #postgres_store_wire_transfer_out */ GNUNET_PQ_make_prepare ( "insert_wire_out", @@ -1826,6 +1830,8 @@ prepare_statements (struct PostgresClosure *pg) ",wire_fee_frac" ",closing_fee_val" ",closing_fee_frac" + ",wad_fee_val" + ",wad_fee_frac" ",start_date" ",end_date" ",master_sig" @@ -1936,6 +1942,8 @@ prepare_statements (struct PostgresClosure *pg) ",wire_fee_frac" ",closing_fee_val" ",closing_fee_frac" + ",wad_fee_val" + ",wad_fee_frac" " FROM wire_fee" " WHERE wire_method=$1" " AND end_date > $2" @@ -2421,6 +2429,8 @@ prepare_statements (struct PostgresClosure *pg) ",wire_fee_frac" ",closing_fee_val" ",closing_fee_frac" + ",wad_fee_val" + ",wad_fee_frac" ",master_sig" " FROM wire_fee" " WHERE wire_fee_serial > $1" @@ -2711,10 +2721,12 @@ prepare_statements (struct PostgresClosure *pg) ",wire_fee_frac" ",closing_fee_val" ",closing_fee_frac" + ",wad_fee_val" + ",wad_fee_frac" ",master_sig" ") VALUES " - "($1, $2, $3, $4, $5, $6, $7, $8, $9);", - 9), + "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11);", + 11), GNUNET_PQ_make_prepare ( "insert_into_table_recoup", "INSERT INTO recoup" @@ -7554,8 +7566,7 @@ postgres_insert_aggregation_tracking ( * @param date for which date do we want the fee? * @param[out] start_date when does the fee go into effect * @param[out] end_date when does the fee end being valid - * @param[out] wire_fee how high is the wire transfer fee - * @param[out] closing_fee how high is the closing fee + * @param[out] fees how high are the wire fees * @param[out] master_sig signature over the above by the exchange master key * @return status of the transaction */ @@ -7565,8 +7576,7 @@ postgres_get_wire_fee (void *cls, struct GNUNET_TIME_Timestamp date, struct GNUNET_TIME_Timestamp *start_date, struct GNUNET_TIME_Timestamp *end_date, - struct TALER_Amount *wire_fee, - struct TALER_Amount *closing_fee, + struct TALER_WireFeeSet *fees, struct TALER_MasterSignatureP *master_sig) { struct PostgresClosure *pg = cls; @@ -7576,11 +7586,18 @@ postgres_get_wire_fee (void *cls, GNUNET_PQ_query_param_end }; struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_timestamp ("start_date", start_date), - GNUNET_PQ_result_spec_timestamp ("end_date", end_date), - TALER_PQ_RESULT_SPEC_AMOUNT ("wire_fee", wire_fee), - TALER_PQ_RESULT_SPEC_AMOUNT ("closing_fee", closing_fee), - GNUNET_PQ_result_spec_auto_from_type ("master_sig", master_sig), + GNUNET_PQ_result_spec_timestamp ("start_date", + start_date), + GNUNET_PQ_result_spec_timestamp ("end_date", + end_date), + TALER_PQ_RESULT_SPEC_AMOUNT ("wire_fee", + &fees->wire), + TALER_PQ_RESULT_SPEC_AMOUNT ("wad_fee", + &fees->wad), + TALER_PQ_RESULT_SPEC_AMOUNT ("closing_fee", + &fees->closing), + GNUNET_PQ_result_spec_auto_from_type ("master_sig", + master_sig), GNUNET_PQ_result_spec_end }; @@ -7598,8 +7615,7 @@ postgres_get_wire_fee (void *cls, * @param type type of wire transfer this fee applies for * @param start_date when does the fee go into effect * @param end_date when does the fee end being valid - * @param wire_fee how high is the wire transfer fee - * @param closing_fee how high is the closing fee + * @param fees how high are the wire fees * @param master_sig signature over the above by the exchange master key * @return transaction status code */ @@ -7608,8 +7624,7 @@ postgres_insert_wire_fee (void *cls, const char *type, struct GNUNET_TIME_Timestamp start_date, struct GNUNET_TIME_Timestamp end_date, - const struct TALER_Amount *wire_fee, - const struct TALER_Amount *closing_fee, + const struct TALER_WireFeeSet *fees, const struct TALER_MasterSignatureP *master_sig) { struct PostgresClosure *pg = cls; @@ -7617,13 +7632,13 @@ postgres_insert_wire_fee (void *cls, GNUNET_PQ_query_param_string (type), GNUNET_PQ_query_param_timestamp (&start_date), GNUNET_PQ_query_param_timestamp (&end_date), - TALER_PQ_query_param_amount (wire_fee), - TALER_PQ_query_param_amount (closing_fee), + TALER_PQ_query_param_amount (&fees->wire), + TALER_PQ_query_param_amount (&fees->closing), + TALER_PQ_query_param_amount (&fees->wad), GNUNET_PQ_query_param_auto_from_type (master_sig), GNUNET_PQ_query_param_end }; - struct TALER_Amount wf; - struct TALER_Amount cf; + struct TALER_WireFeeSet wx; struct TALER_MasterSignatureP sig; struct GNUNET_TIME_Timestamp sd; struct GNUNET_TIME_Timestamp ed; @@ -7634,8 +7649,7 @@ postgres_insert_wire_fee (void *cls, start_date, &sd, &ed, - &wf, - &cf, + &wx, &sig); if (qs < 0) return qs; @@ -7647,14 +7661,9 @@ postgres_insert_wire_fee (void *cls, GNUNET_break (0); return GNUNET_DB_STATUS_HARD_ERROR; } - if (0 != TALER_amount_cmp (wire_fee, - &wf)) - { - GNUNET_break (0); - return GNUNET_DB_STATUS_HARD_ERROR; - } - if (0 != TALER_amount_cmp (closing_fee, - &cf)) + if (0 != + TALER_wire_fee_set_cmp (fees, + &wx)) { GNUNET_break (0); return GNUNET_DB_STATUS_HARD_ERROR; @@ -10230,15 +10239,16 @@ get_wire_fees_cb (void *cls, for (unsigned int i = 0; i < num_results; i++) { struct TALER_MasterSignatureP master_sig; - struct TALER_Amount wire_fee; - struct TALER_Amount closing_fee; + struct TALER_WireFeeSet fees; struct GNUNET_TIME_Timestamp start_date; struct GNUNET_TIME_Timestamp end_date; struct GNUNET_PQ_ResultSpec rs[] = { TALER_PQ_RESULT_SPEC_AMOUNT ("wire_fee", - &wire_fee), + &fees.wire), TALER_PQ_RESULT_SPEC_AMOUNT ("closing_fee", - &closing_fee), + &fees.closing), + TALER_PQ_RESULT_SPEC_AMOUNT ("wad_fee", + &fees.wad), GNUNET_PQ_result_spec_timestamp ("start_date", &start_date), GNUNET_PQ_result_spec_timestamp ("end_date", @@ -10258,8 +10268,7 @@ get_wire_fees_cb (void *cls, return; } ctx->cb (ctx->cb_cls, - &wire_fee, - &closing_fee, + &fees, start_date, end_date, &master_sig); @@ -10604,16 +10613,10 @@ struct WireFeeLookupContext { /** - * Set to the wire fee. Set to invalid if fees conflict over + * Set to the wire fees. Set to invalid if fees conflict over * the given time period. */ - struct TALER_Amount *wire_fee; - - /** - * Set to the closing fee. Set to invalid if fees conflict over - * the given time period. - */ - struct TALER_Amount *closing_fee; + struct TALER_WireFeeSet *fees; /** * Plugin context. @@ -10640,13 +10643,14 @@ wire_fee_by_time_helper (void *cls, for (unsigned int i = 0; iwire_fee, - 0, - sizeof (struct TALER_Amount)); - memset (wlc->closing_fee, + memset (wlc->fees, 0, - sizeof (struct TALER_Amount)); + sizeof (struct TALER_WireFeeSet)); return; } if (0 == i) { - *wlc->wire_fee = wf; - *wlc->closing_fee = cf; + *wlc->fees = fs; continue; } - if ( (GNUNET_YES != - TALER_amount_cmp_currency (&wf, - wlc->wire_fee)) || - (GNUNET_YES != - TALER_amount_cmp_currency (&cf, - wlc->closing_fee)) || - (0 != - TALER_amount_cmp (&wf, - wlc->wire_fee)) || - (0 != - TALER_amount_cmp (&cf, - wlc->closing_fee)) ) + if (0 != + TALER_wire_fee_set_cmp (&fs, + wlc->fees)) { /* invalidate */ - memset (wlc->wire_fee, + memset (wlc->fees, 0, - sizeof (struct TALER_Amount)); - memset (wlc->closing_fee, - 0, - sizeof (struct TALER_Amount)); + sizeof (struct TALER_WireFeeSet)); return; } } @@ -10700,7 +10688,7 @@ wire_fee_by_time_helper (void *cls, /** * Lookup information about known wire fees. Finds all applicable * fees in the given range. If they are identical, returns the - * respective @a wire_fee and @a closing_fee. If any of the fees + * respective @a fees. If any of the fees * differ between @a start_time and @a end_time, the transaction * succeeds BUT returns an invalid amount for both fees. * @@ -10708,11 +10696,8 @@ wire_fee_by_time_helper (void *cls, * @param wire_method the wire method to lookup fees for * @param start_time starting time of fee * @param end_time end time of fee - * @param[out] wire_fee wire fee for that time period; if - * different wire fee exists within this time - * period, an 'invalid' amount is returned. - * @param[out] closing_fee wire fee for that time period; if - * different wire fee exists within this time + * @param[out] fees wire fees for that time period; if + * different fees exists within this time * period, an 'invalid' amount is returned. * @return transaction status code */ @@ -10722,8 +10707,7 @@ postgres_lookup_wire_fee_by_time ( const char *wire_method, struct GNUNET_TIME_Timestamp start_time, struct GNUNET_TIME_Timestamp end_time, - struct TALER_Amount *wire_fee, - struct TALER_Amount *closing_fee) + struct TALER_WireFeeSet *fees) { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { @@ -10733,9 +10717,8 @@ postgres_lookup_wire_fee_by_time ( GNUNET_PQ_query_param_end }; struct WireFeeLookupContext wlc = { - .wire_fee = wire_fee, - .closing_fee = closing_fee, - .pg = pg, + .fees = fees, + .pg = pg }; return GNUNET_PQ_eval_prepared_multi_select (pg->conn, @@ -10834,6 +10817,9 @@ postgres_lookup_serial_by_table (void *cls, case TALER_EXCHANGEDB_RT_WIRE_FEE: statement = "select_serial_by_table_wire_fee"; break; + case TALER_EXCHANGEDB_RT_GLOBAL_FEE: + statement = "select_serial_by_table_global_fee"; + break; case TALER_EXCHANGEDB_RT_RECOUP: statement = "select_serial_by_table_recoup"; break; @@ -11003,6 +10989,10 @@ postgres_lookup_records_by_table (void *cls, statement = "select_above_serial_by_table_wire_fee"; rh = &lrbt_cb_table_wire_fee; break; + case TALER_EXCHANGEDB_RT_GLOBAL_FEE: + statement = "select_above_serial_by_table_global_fee"; + rh = &lrbt_cb_table_global_fee; + break; case TALER_EXCHANGEDB_RT_RECOUP: statement = "select_above_serial_by_table_recoup"; rh = &lrbt_cb_table_recoup; @@ -11138,6 +11128,9 @@ postgres_insert_records_by_table (void *cls, case TALER_EXCHANGEDB_RT_WIRE_FEE: rh = &irbt_cb_table_wire_fee; break; + case TALER_EXCHANGEDB_RT_GLOBAL_FEE: + rh = &irbt_cb_table_global_fee; + break; case TALER_EXCHANGEDB_RT_RECOUP: rh = &irbt_cb_table_recoup; break; diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c index 10390b7fc..012cac645 100644 --- a/src/exchangedb/test_exchangedb.c +++ b/src/exchangedb/test_exchangedb.c @@ -915,23 +915,24 @@ test_wire_fees (void) { struct GNUNET_TIME_Timestamp start_date; struct GNUNET_TIME_Timestamp end_date; - struct TALER_Amount wire_fee; - struct TALER_Amount closing_fee; + struct TALER_WireFeeSet fees; struct TALER_MasterSignatureP master_sig; struct GNUNET_TIME_Timestamp sd; struct GNUNET_TIME_Timestamp ed; - struct TALER_Amount fee; - struct TALER_Amount fee2; + struct TALER_WireFeeSet fees2; struct TALER_MasterSignatureP ms; start_date = GNUNET_TIME_timestamp_get (); end_date = GNUNET_TIME_relative_to_timestamp (GNUNET_TIME_UNIT_MINUTES); GNUNET_assert (GNUNET_OK == TALER_string_to_amount (CURRENCY ":1.424242", - &wire_fee)); + &fees.wire)); GNUNET_assert (GNUNET_OK == TALER_string_to_amount (CURRENCY ":2.424242", - &closing_fee)); + &fees.closing)); + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount (CURRENCY ":3.424242", + &fees.wad)); GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &master_sig, sizeof (master_sig)); @@ -940,8 +941,7 @@ test_wire_fees (void) "wire-method", start_date, end_date, - &wire_fee, - &closing_fee, + &fees, &master_sig)) { GNUNET_break (0); @@ -952,8 +952,7 @@ test_wire_fees (void) "wire-method", start_date, end_date, - &wire_fee, - &closing_fee, + &fees, &master_sig)) { GNUNET_break (0); @@ -967,8 +966,7 @@ test_wire_fees (void) end_date, &sd, &ed, - &fee, - &fee2, + &fees2, &ms)) { GNUNET_break (0); @@ -980,8 +978,7 @@ test_wire_fees (void) start_date, &sd, &ed, - &fee, - &fee2, + &fees2, &ms)) { GNUNET_break (0); @@ -993,10 +990,8 @@ test_wire_fees (void) (GNUNET_TIME_timestamp_cmp (ed, !=, end_date)) || - (0 != TALER_amount_cmp (&fee, - &wire_fee)) || - (0 != TALER_amount_cmp (&fee2, - &closing_fee)) || + (0 != TALER_wire_fee_set_cmp (&fees, + &fees2)) || (0 != GNUNET_memcmp (&ms, &master_sig)) ) { -- cgit v1.2.3