commit ea4ddbc744baf281649db57bb4441d40ca609088
parent 79f095f2c3f125276664ddfe9d92d54996a2a182
Author: Christian Grothoff <christian@grothoff.org>
Date: Sat, 29 Mar 2025 15:24:13 +0100
fix tops rules
Diffstat:
7 files changed, 92 insertions(+), 49 deletions(-)
diff --git a/src/exchangedb/0009-batch_deposits.sql b/src/exchangedb/0009-batch_deposits.sql
@@ -0,0 +1,54 @@
+--
+-- This file is part of TALER
+-- Copyright (C) 2025 Taler Systems SA
+--
+-- TALER is free software; you can redistribute it and/or modify it under the
+-- terms of the GNU General Public License as published by the Free Software
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+--
+
+CREATE FUNCTION alter_table_batch_deposits9(
+ IN partition_suffix TEXT DEFAULT NULL
+)
+RETURNS VOID
+LANGUAGE plpgsql
+AS $$
+BEGIN
+ PERFORM create_partitioned_table(
+ 'ALTER TABLE %I'
+ ' ADD COLUMN total_amount taler_amount'
+ ' DEFAULT NULL'
+ ';',
+ 'batch_deposits'
+ ,''
+ ,partition_suffix
+ );
+
+ PERFORM comment_partitioned_column(
+ 'total amount, NULL allowed for legacy entries (pre-1.0)'
+ ,'total_amount'
+ ,'batch_deposits'
+ ,partition_suffix
+ );
+END $$;
+
+
+INSERT INTO exchange_tables
+ (name
+ ,version
+ ,action
+ ,partitioned
+ ,by_range)
+ VALUES
+ ('batch_deposits9'
+ ,'exchange-0009'
+ ,'alter'
+ ,TRUE
+ ,FALSE);
diff --git a/src/exchangedb/exchange-0009.sql.in b/src/exchangedb/exchange-0009.sql.in
@@ -26,6 +26,7 @@ COMMENT ON INDEX exchange_tables_by_pending
#include "0009-age_withdraw.sql"
+#include "0009-batch_deposits.sql"
#include "0009-withdraw.sql"
#include "0009-recoup.sql"
#include "0009-statistics.sql"
diff --git a/src/exchangedb/exchange_do_deposit.sql b/src/exchangedb/exchange_do_deposit.sql
@@ -37,6 +37,7 @@ CREATE FUNCTION exchange_do_deposit(
IN ina_coin_pub BYTEA[],
IN ina_coin_sig BYTEA[],
IN ina_amount_with_fee taler_amount[],
+ IN in_total_amount taler_amount,
OUT out_exchange_timestamp INT8,
OUT out_insufficient_balance_coin_index INT4, -- index of coin with bad balance, NULL if none
OUT out_conflict BOOL
@@ -100,6 +101,7 @@ INSERT INTO batch_deposits
,wire_target_h_payto
,policy_details_serial_id
,policy_blocked
+ ,total_amount
)
VALUES
(in_shard
@@ -114,7 +116,8 @@ INSERT INTO batch_deposits
,in_wire_salt
,in_wire_target_h_payto
,in_policy_details_serial_id
- ,in_policy_blocked)
+ ,in_policy_blocked
+ ,in_total_amount)
ON CONFLICT DO NOTHING -- for CONFLICT ON (merchant_pub, h_contract_terms)
RETURNING
batch_deposit_serial_id
diff --git a/src/exchangedb/exchange_statistics_helpers.sql b/src/exchangedb/exchange_statistics_helpers.sql
@@ -795,7 +795,7 @@ BEGIN
min_slot = my_ranges[my_i - 1];
END IF;
end_slot = my_ranges[my_i];
- RAISE NOTICE 'Coarsening from [%,%) at %', my_time - end_slot, my_time - min_slot, my_precision;
+-- RAISE NOTICE 'Coarsening from [%,%) at %', my_time - end_slot, my_time - min_slot, my_precision;
LOOP
EXIT WHEN min_slot >= end_slot;
@@ -805,22 +805,22 @@ BEGIN
MIN(nevent_serial_id) AS rep_serial_id
INTO my_sum
FROM exchange_statistic_counter_event
- WHERE h_payto=my_instance
+ WHERE h_payto=my_h_payto
AND imeta_serial_id=my_meta
AND slot >= my_time - max_slot
AND slot < my_time - min_slot;
- RAISE NOTICE 'Found % entries between [%,%)', my_sum.matches, my_time - max_slot, my_time - min_slot;
+-- RAISE NOTICE 'Found % entries between [%,%)', my_sum.matches, my_time - max_slot, my_time - min_slot;
-- we only proceed if we had more then one match (optimization)
IF FOUND AND my_sum.matches > 1
THEN
my_total = my_sum.total;
- RAISE NOTICE 'combining % entries to representative % for slots [%-%)', my_sum.matches, my_sum.rep_serial_id, my_time - max_slot, my_time - min_slot;
+-- RAISE NOTICE 'combining % entries to representative % for slots [%-%)', my_sum.matches, my_sum.rep_serial_id, my_time - max_slot, my_time - min_slot;
-- combine entries
DELETE FROM exchange_statistic_counter_event
- WHERE h_payto=my_instance
+ WHERE h_payto=my_h_payto
AND imeta_serial_id=my_meta
AND slot >= my_time - max_slot
AND slot < my_time - min_slot
@@ -829,7 +829,7 @@ BEGIN
UPDATE exchange_statistic_counter_event SET
delta = my_total
WHERE imeta_serial_id = my_meta
- AND h_payto = my_instance
+ AND h_payto = my_h_payto
AND nevent_serial_id = my_sum.rep_serial_id;
END IF;
min_slot = min_slot + my_precision;
@@ -837,13 +837,13 @@ BEGIN
END LOOP; -- my_i loop
-- Finally, delete all events beyond the range we care about
- RAISE NOTICE 'deleting entries of %/% before % - % = %', my_instance, my_meta, my_time, my_ranges[array_length(my_ranges,1)], my_time - my_ranges[array_length(my_ranges,1)];
+-- RAISE NOTICE 'deleting entries of %/% before % - % = %', my_h_payto, my_meta, my_time, my_ranges[array_length(my_ranges,1)], my_time - my_ranges[array_length(my_ranges,1)];
DELETE FROM exchange_statistic_counter_event
- WHERE h_payto=my_instance
+ WHERE h_payto=my_h_payto
AND imeta_serial_id=my_meta
AND slot < my_time - my_ranges[array_length(my_ranges,1)];
END LOOP; -- my_rec loop
- END LOOP; -- my_instance loop
+ END LOOP; -- my_h_payto loop
END $$;
COMMENT ON PROCEDURE exchange_statistic_counter_gc
IS 'Performs garbage collection and compaction of the exchange_statistic_counter_event table';
@@ -908,13 +908,13 @@ BEGIN
END IF;
end_slot = my_ranges[my_i];
- RAISE NOTICE 'Coarsening from [%,%) at %', my_time - end_slot, my_time - min_slot, my_precision;
+-- RAISE NOTICE 'Coarsening from [%,%) at %', my_time - end_slot, my_time - min_slot, my_precision;
LOOP
EXIT WHEN min_slot >= end_slot;
max_slot = min_slot + my_precision;
- SELECT SUM(delta_value) AS total_val,
- SUM(delta_frac) AS total_frac,
- COUNT(*) AS matches,
+ SELECT SUM((delta).val) AS total_val,
+ SUM((delta).frac) AS total_frac,
+ COUNT(*) AS matches,
MIN(aevent_serial_id) AS rep_serial_id
INTO my_sum
FROM exchange_statistic_amount_event
@@ -938,8 +938,8 @@ BEGIN
AND aevent_serial_id > my_sum.rep_serial_id;
-- Now update the representative to the sum
UPDATE exchange_statistic_amount_event SET
- delta_value = my_total_value
- ,delta_frac = my_total_frac
+ delta.val = my_total_value
+ ,delta.frac = my_total_frac
WHERE imeta_serial_id = my_meta
AND h_payto = my_h_payto
AND aevent_serial_id = my_sum.rep_serial_id;
@@ -949,7 +949,7 @@ BEGIN
END LOOP; -- my_i loop
-- Finally, delete all events beyond the range we care about
- RAISE NOTICE 'deleting entries of %/% before % - % = %', my_h_payto, my_meta, my_time, my_ranges[array_length(my_ranges,1)], my_time - my_ranges[array_length(my_ranges,1)];
+-- RAISE NOTICE 'deleting entries of %/% before % - % = %', my_h_payto, my_meta, my_time, my_ranges[array_length(my_ranges,1)], my_time - my_ranges[array_length(my_ranges,1)];
DELETE FROM exchange_statistic_amount_event
WHERE h_payto=my_h_payto
AND imeta_serial_id=my_meta
diff --git a/src/exchangedb/pg_do_deposit.c b/src/exchangedb/pg_do_deposit.c
@@ -41,6 +41,7 @@ TEH_PG_do_deposit (
const struct TALER_CoinSpendPublicKeyP *coin_pubs[GNUNET_NZL (bd->num_cdis)];
const struct TALER_CoinSpendSignatureP *coin_sigs[GNUNET_NZL (bd->num_cdis)];
struct TALER_Amount amounts_with_fee[GNUNET_NZL (bd->num_cdis)];
+ struct TALER_Amount total_amount;
struct TALER_NormalizedPaytoHashP h_normalized_payto;
struct GNUNET_PQ_QueryParam params[] = {
/* data for batch_deposits */
@@ -76,6 +77,8 @@ TEH_PG_do_deposit (
TALER_PQ_query_param_array_amount (bd->num_cdis,
amounts_with_fee,
pg->conn),
+ TALER_PQ_query_param_amount (pg->conn,
+ &total_amount),
GNUNET_PQ_query_param_end
};
bool no_time;
@@ -94,6 +97,7 @@ TEH_PG_do_deposit (
};
enum GNUNET_DB_QueryStatus qs;
+ GNUNET_assert (0 < bd->num_cdis);
TALER_full_payto_normalize_and_hash (bd->receiver_wire_account,
&h_normalized_payto);
for (unsigned int i = 0; i < bd->num_cdis; i++)
@@ -101,6 +105,17 @@ TEH_PG_do_deposit (
const struct TALER_EXCHANGEDB_CoinDepositInformation *cdi
= &bd->cdis[i];
+ if (0 == i)
+ {
+ total_amount = cdi->amount_with_fee;
+ }
+ else
+ {
+ GNUNET_assert (0 <=
+ TALER_amount_add (&total_amount,
+ &total_amount,
+ &cdi->amount_with_fee));
+ }
amounts_with_fee[i] = cdi->amount_with_fee;
coin_pubs[i] = &cdi->coin.coin_pub;
coin_sigs[i] = &cdi->csig;
@@ -116,7 +131,7 @@ TEH_PG_do_deposit (
",out_insufficient_balance_coin_index AS insufficient_balance_coin_index"
",out_conflict AS conflicted"
" FROM exchange_do_deposit"
- " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18);")
+ " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19);")
;
qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"call_deposit",
diff --git a/src/exchangedb/tops-0001.sql b/src/exchangedb/tops-0001.sql
@@ -88,9 +88,6 @@ AS $$
DECLARE
my_h_payto BYTEA; -- normalized h_payto of target account
my_rec RECORD;
- my_vsum INT8;
- my_fsum INT8;
- my_batch_amount taler_amount; -- sum of all coins (incl. fees)
my_last_year taler_amount; -- sum of deposits this year
my_last_month taler_amount; -- sum of deposits this month
my_old_rules RECORD;
@@ -103,37 +100,11 @@ BEGIN
FROM wire_targets wt
WHERE wire_target_h_payto = NEW.wire_target_h_payto;
- -- FIXME: this does not work, coin_deposits is only initialized LATER
- -- in exchange_do_deposit.sql;
- -- Solution: add a new column with the sum?
- FOR my_rec IN
- SELECT amount_with_fee
- FROM coin_deposits cdeps
- WHERE batch_deposit_serial_id = NEW.batch_deposit_serial_id
- LOOP
- RAISE NOTICE 'XXXX has %', my_rec;
- END LOOP;
- SELECT SUM((cdeps.amount_with_fee).val) AS vsum,
- SUM((cdeps.amount_with_fee).frac) AS fsum
- INTO my_rec
- FROM coin_deposits cdeps
- WHERE batch_deposit_serial_id = NEW.batch_deposit_serial_id;
- IF NOT FOUND
- THEN
- RAISE NOTICE 'Invariant failed, no coin deposits for batch deposit';
- RETURN NEW;
- END IF;
- RAISE NOTICE 'XXXZ SELECT yielded % - %',FOUND,my_rec;
- my_vsum = my_rec.vsum;
- my_fsum = my_rec.fsum;
- RAISE NOTICE 'XXXY Batch deposit of %.%',my_vsum,my_fsum;
- my_batch_amount.val = my_vsum + my_fsum / 100000000;
- my_batch_amount.frac = my_fsum % 100000000;
CALL exchange_do_bump_amount_stat
('deposit-volume'
,my_h_payto
,CURRENT_TIMESTAMP(0)::TIMESTAMP
- ,my_batch_amount);
+ ,NEW.total_amount);
-- FIXME: this is just for testing, I want to also check
-- the 'counter'-based functions.
diff --git a/src/testing/taler-unified-setup.sh b/src/testing/taler-unified-setup.sh
@@ -512,7 +512,6 @@ then
taler-exchange-dbinit \
-c "$CONF" \
--reset
-# -e tops
$USE_VALGRIND taler-exchange-secmod-eddsa \
-c "$CONF" \
-L "$LOGLEVEL" \