commit 280eeebcd3e80c1bcaa22e347367c67f6c0ee61f
parent 030de55b4925e6f71e47f9c5962bfbbf4138d577
Author: Christian Grothoff <christian@grothoff.org>
Date: Tue, 26 May 2026 23:51:48 +0200
more SQL bugfixes, DCE
Diffstat:
10 files changed, 20 insertions(+), 944 deletions(-)
diff --git a/src/auditor/taler-auditor-sync.c b/src/auditor/taler-auditor-sync.c
@@ -27,7 +27,6 @@
#include "exchange-database/add_denomination_key.h"
#include "exchange-database/add_policy_fulfillment_proof.h"
#include "exchange-database/aggregate.h"
-#include "exchange-database/batch_ensure_coin_known.h"
#include "exchange-database/begin_revolving_shard.h"
#include "exchange-database/begin_shard.h"
#include "exchange-database/clear_aml_lock.h"
diff --git a/src/exchangedb/batch_ensure_coin_known.c b/src/exchangedb/batch_ensure_coin_known.c
@@ -1,457 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022 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/>
- */
-/**
- * @file exchangedb/batch_ensure_coin_known.c
- * @brief Implementation of the batch_ensure_coin_known function for Postgres
- * @author Christian Grothoff
- *
- * FIXME-#9373: use the array support for postgres to simplify this code!
- *
- */
-#include "exchangedb_lib.h"
-#include "taler/taler_pq_lib.h"
-#include "exchange-database/batch_ensure_coin_known.h"
-#include "helper.h"
-
-
-static enum GNUNET_DB_QueryStatus
-insert1 (struct TALER_EXCHANGEDB_PostgresContext *pg,
- const struct TALER_CoinPublicInfo coin[1],
- struct TALER_EXCHANGEDB_CoinInfo result[1])
-{
- enum GNUNET_DB_QueryStatus qs;
- bool is_denom_pub_hash_null = false;
- bool is_age_hash_null = false;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (&coin[0].coin_pub),
- GNUNET_PQ_query_param_auto_from_type (&coin[0].denom_pub_hash),
- GNUNET_PQ_query_param_auto_from_type (&coin[0].h_age_commitment),
- TALER_PQ_query_param_denom_sig (&coin[0].denom_sig),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("existed",
- &result[0].existed),
- GNUNET_PQ_result_spec_uint64 ("known_coin_id",
- &result[0].known_coin_id),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
- &result[0].denom_hash),
- &is_denom_pub_hash_null),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
- &result[0].h_age_commitment),
- &is_age_hash_null),
- GNUNET_PQ_result_spec_end
- };
-
- PREPARE (pg,
- "batch1_known_coin",
- "SELECT"
- " existed1 AS existed"
- ",known_coin_id1 AS known_coin_id"
- ",denom_pub_hash1 AS denom_hash"
- ",age_commitment_hash1 AS h_age_commitment"
- " FROM exchange_do_batch1_known_coin"
- " ($1, $2, $3, $4);"
- );
- qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "batch1_known_coin",
- params,
- rs);
- switch (qs)
- {
- case GNUNET_DB_STATUS_HARD_ERROR:
- GNUNET_break (0);
- return qs;
- case GNUNET_DB_STATUS_SOFT_ERROR:
- return qs;
- case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- GNUNET_break (0); /* should be impossible */
- return GNUNET_DB_STATUS_HARD_ERROR;
- case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
- break; /* continued below */
- }
-
- if ( (! is_denom_pub_hash_null) &&
- (0 != GNUNET_memcmp (&result[0].denom_hash,
- &coin->denom_pub_hash)) )
- {
- GNUNET_break_op (0);
- result[0].denom_conflict = true;
- }
-
- if ( (! is_denom_pub_hash_null) &&
- (0 != GNUNET_memcmp (&result[0].denom_hash,
- &coin[0].denom_pub_hash)) )
- {
- GNUNET_break_op (0);
- result[0].denom_conflict = true;
- }
-
- result[0].age_conflict = TALER_AgeCommitmentHashP_NoConflict;
-
- if (is_age_hash_null != coin[0].no_age_commitment)
- {
- if (is_age_hash_null)
- {
- GNUNET_break_op (0);
- result[0].age_conflict = TALER_AgeCommitmentHashP_NullExpected;
- }
- else
- {
- GNUNET_break_op (0);
- result[0].age_conflict = TALER_AgeCommitmentHashP_ValueExpected;
- }
- }
- else if ( (! is_age_hash_null) &&
- (0 != GNUNET_memcmp (&result[0].h_age_commitment,
- &coin[0].h_age_commitment)) )
- {
- GNUNET_break_op (0);
- result[0].age_conflict = TALER_AgeCommitmentHashP_ValueDiffers;
- }
-
- return qs;
-}
-
-
-static enum GNUNET_DB_QueryStatus
-insert2 (struct TALER_EXCHANGEDB_PostgresContext *pg,
- const struct TALER_CoinPublicInfo coin[2],
- struct TALER_EXCHANGEDB_CoinInfo result[2])
-{
- enum GNUNET_DB_QueryStatus qs;
- bool is_denom_pub_hash_null[2] = {false, false};
- bool is_age_hash_null[2] = {false, false};
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (&coin[0].coin_pub),
- GNUNET_PQ_query_param_auto_from_type (&coin[0].denom_pub_hash),
- GNUNET_PQ_query_param_auto_from_type (&coin[0].h_age_commitment),
- TALER_PQ_query_param_denom_sig (&coin[0].denom_sig),
-
- GNUNET_PQ_query_param_auto_from_type (&coin[1].coin_pub),
- GNUNET_PQ_query_param_auto_from_type (&coin[1].denom_pub_hash),
- GNUNET_PQ_query_param_auto_from_type (&coin[1].h_age_commitment),
- TALER_PQ_query_param_denom_sig (&coin[0].denom_sig),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("existed",
- &result[0].existed),
- GNUNET_PQ_result_spec_uint64 ("known_coin_id",
- &result[0].known_coin_id),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
- &result[0].denom_hash),
- &is_denom_pub_hash_null[0]),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
- &result[0].h_age_commitment),
- &is_age_hash_null[0]),
- GNUNET_PQ_result_spec_bool ("existed2",
- &result[1].existed),
- GNUNET_PQ_result_spec_uint64 ("known_coin_id2",
- &result[1].known_coin_id),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash2",
- &result[1].denom_hash),
- &is_denom_pub_hash_null[1]),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash2",
- &result[1].h_age_commitment),
- &is_age_hash_null[1]),
- GNUNET_PQ_result_spec_end
- };
-
- PREPARE (pg,
- "batch2_known_coin",
- "SELECT"
- " existed1 AS existed"
- ",known_coin_id1 AS known_coin_id"
- ",denom_pub_hash1 AS denom_hash"
- ",age_commitment_hash1 AS h_age_commitment"
- ",existed2 AS existed2"
- ",known_coin_id2 AS known_coin_id2"
- ",denom_pub_hash2 AS denom_hash2"
- ",age_commitment_hash2 AS h_age_commitment2"
- " FROM exchange_do_batch2_known_coin"
- " ($1, $2, $3, $4, $5, $6, $7, $8);"
- );
- qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "batch2_known_coin",
- params,
- rs);
- switch (qs)
- {
- case GNUNET_DB_STATUS_HARD_ERROR:
- GNUNET_break (0);
- return qs;
- case GNUNET_DB_STATUS_SOFT_ERROR:
- return qs;
- case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- GNUNET_break (0); /* should be impossible */
- return GNUNET_DB_STATUS_HARD_ERROR;
- case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
- break; /* continued below */
- }
-
- for (int i = 0; i < 2; i++)
- {
- if ( (! is_denom_pub_hash_null[i]) &&
- (0 != GNUNET_memcmp (&result[i].denom_hash,
- &coin[i].denom_pub_hash)) )
- {
- GNUNET_break_op (0);
- result[i].denom_conflict = true;
- }
-
- result[i].age_conflict = TALER_AgeCommitmentHashP_NoConflict;
-
- if (is_age_hash_null[i] != coin[i].no_age_commitment)
- {
- if (is_age_hash_null[i])
- {
- GNUNET_break_op (0);
- result[i].age_conflict = TALER_AgeCommitmentHashP_NullExpected;
- }
- else
- {
- GNUNET_break_op (0);
- result[i].age_conflict = TALER_AgeCommitmentHashP_ValueExpected;
- }
- }
- else if ( (! is_age_hash_null[i]) &&
- (0 != GNUNET_memcmp (&result[i].h_age_commitment,
- &coin[i].h_age_commitment)) )
- {
- GNUNET_break_op (0);
- result[i].age_conflict = TALER_AgeCommitmentHashP_ValueDiffers;
- }
- }
-
- return qs;
-}
-
-
-static enum GNUNET_DB_QueryStatus
-insert4 (struct TALER_EXCHANGEDB_PostgresContext *pg,
- const struct TALER_CoinPublicInfo coin[4],
- struct TALER_EXCHANGEDB_CoinInfo result[4])
-{
- enum GNUNET_DB_QueryStatus qs;
- bool is_denom_pub_hash_null[4] = {false, false, false, false};
- bool is_age_hash_null[4] = {false, false, false, false};
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (&coin[0].coin_pub),
- GNUNET_PQ_query_param_auto_from_type (&coin[0].denom_pub_hash),
- GNUNET_PQ_query_param_auto_from_type (&coin[0].h_age_commitment),
- TALER_PQ_query_param_denom_sig (&coin[0].denom_sig),
-
- GNUNET_PQ_query_param_auto_from_type (&coin[1].coin_pub),
- GNUNET_PQ_query_param_auto_from_type (&coin[1].denom_pub_hash),
- GNUNET_PQ_query_param_auto_from_type (&coin[1].h_age_commitment),
- TALER_PQ_query_param_denom_sig (&coin[0].denom_sig),
-
- GNUNET_PQ_query_param_auto_from_type (&coin[2].coin_pub),
- GNUNET_PQ_query_param_auto_from_type (&coin[2].denom_pub_hash),
- GNUNET_PQ_query_param_auto_from_type (&coin[2].h_age_commitment),
- TALER_PQ_query_param_denom_sig (&coin[2].denom_sig),
-
- GNUNET_PQ_query_param_auto_from_type (&coin[3].coin_pub),
- GNUNET_PQ_query_param_auto_from_type (&coin[3].denom_pub_hash),
- GNUNET_PQ_query_param_auto_from_type (&coin[3].h_age_commitment),
- TALER_PQ_query_param_denom_sig (&coin[3].denom_sig),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("existed",
- &result[0].existed),
- GNUNET_PQ_result_spec_uint64 ("known_coin_id",
- &result[0].known_coin_id),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
- &result[0].denom_hash),
- &is_denom_pub_hash_null[0]),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
- &result[0].h_age_commitment),
- &is_age_hash_null[0]),
- GNUNET_PQ_result_spec_bool ("existed2",
- &result[1].existed),
- GNUNET_PQ_result_spec_uint64 ("known_coin_id2",
- &result[1].known_coin_id),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash2",
- &result[1].denom_hash),
- &is_denom_pub_hash_null[1]),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash2",
- &result[1].h_age_commitment),
- &is_age_hash_null[1]),
- GNUNET_PQ_result_spec_bool ("existed3",
- &result[2].existed),
- GNUNET_PQ_result_spec_uint64 ("known_coin_id3",
- &result[2].known_coin_id),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash3",
- &result[2].denom_hash),
- &is_denom_pub_hash_null[2]),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash3",
- &result[2].h_age_commitment),
- &is_age_hash_null[2]),
- GNUNET_PQ_result_spec_bool ("existed4",
- &result[3].existed),
- GNUNET_PQ_result_spec_uint64 ("known_coin_id4",
- &result[3].known_coin_id),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash4",
- &result[3].denom_hash),
- &is_denom_pub_hash_null[3]),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash4",
- &result[3].h_age_commitment),
- &is_age_hash_null[3]),
- GNUNET_PQ_result_spec_end
- };
-
- PREPARE (pg,
- "batch4_known_coin",
- "SELECT"
- " existed1 AS existed"
- ",known_coin_id1 AS known_coin_id"
- ",denom_pub_hash1 AS denom_hash"
- ",age_commitment_hash1 AS h_age_commitment"
- ",existed2 AS existed2"
- ",known_coin_id2 AS known_coin_id2"
- ",denom_pub_hash2 AS denom_hash2"
- ",age_commitment_hash2 AS h_age_commitment2"
- ",existed3 AS existed3"
- ",known_coin_id3 AS known_coin_id3"
- ",denom_pub_hash3 AS denom_hash3"
- ",age_commitment_hash3 AS h_age_commitment3"
- ",existed4 AS existed4"
- ",known_coin_id4 AS known_coin_id4"
- ",denom_pub_hash4 AS denom_hash4"
- ",age_commitment_hash4 AS h_age_commitment4"
- " FROM exchange_do_batch2_known_coin"
- " ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16);"
- );
- qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "batch4_known_coin",
- params,
- rs);
- switch (qs)
- {
- case GNUNET_DB_STATUS_HARD_ERROR:
- GNUNET_break (0);
- return qs;
- case GNUNET_DB_STATUS_SOFT_ERROR:
- return qs;
- case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- GNUNET_break (0); /* should be impossible */
- return GNUNET_DB_STATUS_HARD_ERROR;
- case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
- break; /* continued below */
- }
-
- for (int i = 0; i < 4; i++)
- {
- if ( (! is_denom_pub_hash_null[i]) &&
- (0 != GNUNET_memcmp (&result[i].denom_hash,
- &coin[i].denom_pub_hash)) )
- {
- GNUNET_break_op (0);
- result[i].denom_conflict = true;
- }
-
- result[i].age_conflict = TALER_AgeCommitmentHashP_NoConflict;
-
- if (is_age_hash_null[i] != coin[i].no_age_commitment)
- {
- if (is_age_hash_null[i])
- {
- GNUNET_break_op (0);
- result[i].age_conflict = TALER_AgeCommitmentHashP_NullExpected;
- }
- else
- {
- GNUNET_break_op (0);
- result[i].age_conflict = TALER_AgeCommitmentHashP_ValueExpected;
- }
- }
- else if ( (! is_age_hash_null[i]) &&
- (0 != GNUNET_memcmp (&result[i].h_age_commitment,
- &coin[i].h_age_commitment)) )
- {
- GNUNET_break_op (0);
- result[i].age_conflict = TALER_AgeCommitmentHashP_ValueDiffers;
- }
- }
-
- return qs;
-}
-
-
-enum GNUNET_DB_QueryStatus
-TALER_EXCHANGEDB_batch_ensure_coin_known (
- struct TALER_EXCHANGEDB_PostgresContext *pg,
- const struct TALER_CoinPublicInfo *coin,
- struct TALER_EXCHANGEDB_CoinInfo *result,
- unsigned int coin_length,
- unsigned int batch_size)
-{
- enum GNUNET_DB_QueryStatus qs = 0;
- unsigned int i = 0;
-
- while ( (qs >= 0) &&
- (i < coin_length) )
- {
- unsigned int bs = GNUNET_MIN (batch_size,
- coin_length - i);
- if (bs >= 4)
- {
- qs = insert4 (pg,
- &coin[i],
- &result[i]);
- i += 4;
- continue;
- }
- switch (bs)
- {
- case 3:
- case 2:
- qs = insert2 (pg,
- &coin[i],
- &result[i]);
- i += 2;
- break;
- case 1:
- qs = insert1 (pg,
- &coin[i],
- &result[i]);
- i += 1;
- break;
- case 0:
- GNUNET_assert (0);
- break;
- }
- } /* end while */
- if (qs < 0)
- return qs;
- return i;
-}
diff --git a/src/exchangedb/batch_ensure_coin_known.sql b/src/exchangedb/batch_ensure_coin_known.sql
@@ -1,469 +0,0 @@
---
--- This file is part of TALER
--- Copyright (C) 2014--2022 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 OR REPLACE FUNCTION exchange_do_batch4_known_coin(
- IN in_coin_pub1 BYTEA,
- IN in_denom_pub_hash1 BYTEA,
- IN in_h_age_commitment1 BYTEA,
- IN in_denom_sig1 BYTEA,
- IN in_coin_pub2 BYTEA,
- IN in_denom_pub_hash2 BYTEA,
- IN in_h_age_commitment2 BYTEA,
- IN in_denom_sig2 BYTEA,
- IN in_coin_pub3 BYTEA,
- IN in_denom_pub_hash3 BYTEA,
- IN in_h_age_commitment3 BYTEA,
- IN in_denom_sig3 BYTEA,
- IN in_coin_pub4 BYTEA,
- IN in_denom_pub_hash4 BYTEA,
- IN in_h_age_commitment4 BYTEA,
- IN in_denom_sig4 BYTEA,
- OUT existed1 BOOLEAN,
- OUT existed2 BOOLEAN,
- OUT existed3 BOOLEAN,
- OUT existed4 BOOLEAN,
- OUT known_coin_id1 INT8,
- OUT known_coin_id2 INT8,
- OUT known_coin_id3 INT8,
- OUT known_coin_id4 INT8,
- OUT denom_pub_hash1 BYTEA,
- OUT denom_pub_hash2 BYTEA,
- OUT denom_pub_hash3 BYTEA,
- OUT denom_pub_hash4 BYTEA,
- OUT age_commitment_hash1 BYTEA,
- OUT age_commitment_hash2 BYTEA,
- OUT age_commitment_hash3 BYTEA,
- OUT age_commitment_hash4 BYTEA)
-LANGUAGE plpgsql
-AS $$
-BEGIN
-WITH dd AS (
-SELECT
- denominations_serial,
- coin
- FROM denominations
- WHERE denom_pub_hash
- IN
- (in_denom_pub_hash1,
- in_denom_pub_hash2,
- in_denom_pub_hash3,
- in_denom_pub_hash4)
- ),--dd
- input_rows AS (
- VALUES
- (in_coin_pub1,
- in_denom_pub_hash1,
- in_h_age_commitment1,
- in_denom_sig1),
- (in_coin_pub2,
- in_denom_pub_hash2,
- in_h_age_commitment2,
- in_denom_sig2),
- (in_coin_pub3,
- in_denom_pub_hash3,
- in_h_age_commitment3,
- in_denom_sig3),
- (in_coin_pub4,
- in_denom_pub_hash4,
- in_h_age_commitment4,
- in_denom_sig4)
- ),--ir
- ins AS (
- INSERT INTO known_coins (
- coin_pub,
- denominations_serial,
- age_commitment_hash,
- denom_sig,
- remaining
- )
- SELECT
- ir.coin_pub,
- dd.denominations_serial,
- ir.age_commitment_hash,
- ir.denom_sig,
- dd.coin
- FROM input_rows ir
- JOIN dd
- ON dd.denom_pub_hash = ir.denom_pub_hash
- ON CONFLICT DO NOTHING
- RETURNING known_coin_id
- ),--kc
- exists AS (
- SELECT
- CASE
- WHEN
- ins.known_coin_id IS NOT NULL
- THEN
- FALSE
- ELSE
- TRUE
- END AS existed,
- ins.known_coin_id,
- dd.denom_pub_hash,
- kc.age_commitment_hash
- FROM input_rows ir
- LEFT JOIN ins
- ON ins.coin_pub = ir.coin_pub
- LEFT JOIN known_coins kc
- ON kc.coin_pub = ir.coin_pub
- LEFT JOIN dd
- ON dd.denom_pub_hash = ir.denom_pub_hash
- )--exists
-SELECT
- exists.existed AS existed1,
- exists.known_coin_id AS known_coin_id1,
- exists.denom_pub_hash AS denom_pub_hash1,
- exists.age_commitment_hash AS age_commitment_hash1,
- (
- SELECT exists.existed
- FROM exists
- WHERE exists.denom_pub_hash = in_denom_pub_hash2
- ) AS existed2,
- (
- SELECT exists.known_coin_id
- FROM exists
- WHERE exists.denom_pub_hash = in_denom_pub_hash2
- ) AS known_coin_id2,
- (
- SELECT exists.denom_pub_hash
- FROM exists
- WHERE exists.denom_pub_hash = in_denom_pub_hash2
- ) AS denom_pub_hash2,
- (
- SELECT exists.age_commitment_hash
- FROM exists
- WHERE exists.denom_pub_hash = in_denom_pub_hash2
- )AS age_commitment_hash2,
- (
- SELECT exists.existed
- FROM exists
- WHERE exists.denom_pub_hash = in_denom_pub_hash3
- ) AS existed3,
- (
- SELECT exists.known_coin_id
- FROM exists
- WHERE exists.denom_pub_hash = in_denom_pub_hash3
- ) AS known_coin_id3,
- (
- SELECT exists.denom_pub_hash
- FROM exists
- WHERE exists.denom_pub_hash = in_denom_pub_hash3
- ) AS denom_pub_hash3,
- (
- SELECT exists.age_commitment_hash
- FROM exists
- WHERE exists.denom_pub_hash = in_denom_pub_hash3
- )AS age_commitment_hash3,
- (
- SELECT exists.existed
- FROM exists
- WHERE exists.denom_pub_hash = in_denom_pub_hash4
- ) AS existed4,
- (
- SELECT exists.known_coin_id
- FROM exists
- WHERE exists.denom_pub_hash = in_denom_pub_hash4
- ) AS known_coin_id4,
- (
- SELECT exists.denom_pub_hash
- FROM exists
- WHERE exists.denom_pub_hash = in_denom_pub_hash4
- ) AS denom_pub_hash4,
- (
- SELECT exists.age_commitment_hash
- FROM exists
- WHERE exists.denom_pub_hash = in_denom_pub_hash4
- )AS age_commitment_hash4
-FROM exists;
-
-RETURN;
-END $$;
-
-
-CREATE OR REPLACE FUNCTION exchange_do_batch2_known_coin(
- IN in_coin_pub1 BYTEA,
- IN in_denom_pub_hash1 BYTEA,
- IN in_h_age_commitment1 BYTEA,
- IN in_denom_sig1 BYTEA,
- IN in_coin_pub2 BYTEA,
- IN in_denom_pub_hash2 BYTEA,
- IN in_h_age_commitment2 BYTEA,
- IN in_denom_sig2 BYTEA,
- OUT existed1 BOOLEAN,
- OUT existed2 BOOLEAN,
- OUT known_coin_id1 INT8,
- OUT known_coin_id2 INT8,
- OUT denom_pub_hash1 BYTEA,
- OUT denom_pub_hash2 BYTEA,
- OUT age_commitment_hash1 BYTEA,
- OUT age_commitment_hash2 BYTEA)
-LANGUAGE plpgsql
-AS $$
-BEGIN
-WITH dd AS (
-SELECT
- denominations_serial,
- coin
- FROM denominations
- WHERE denom_pub_hash
- IN
- (in_denom_pub_hash1,
- in_denom_pub_hash2)
- ),--dd
- input_rows AS (
- VALUES
- (in_coin_pub1,
- in_denom_pub_hash1,
- in_h_age_commitment1,
- in_denom_sig1),
- (in_coin_pub2,
- in_denom_pub_hash2,
- in_h_age_commitment2,
- in_denom_sig2)
- ),--ir
- ins AS (
- INSERT INTO known_coins (
- coin_pub,
- denominations_serial,
- age_commitment_hash,
- denom_sig,
- remaining
- )
- SELECT
- ir.coin_pub,
- dd.denominations_serial,
- ir.age_commitment_hash,
- ir.denom_sig,
- dd.coin
- FROM input_rows ir
- JOIN dd
- ON dd.denom_pub_hash = ir.denom_pub_hash
- ON CONFLICT DO NOTHING
- RETURNING known_coin_id
- ),--kc
- exists AS (
- SELECT
- CASE
- WHEN ins.known_coin_id IS NOT NULL
- THEN
- FALSE
- ELSE
- TRUE
- END AS existed,
- ins.known_coin_id,
- dd.denom_pub_hash,
- kc.age_commitment_hash
- FROM input_rows ir
- LEFT JOIN ins
- ON ins.coin_pub = ir.coin_pub
- LEFT JOIN known_coins kc
- ON kc.coin_pub = ir.coin_pub
- LEFT JOIN dd
- ON dd.denom_pub_hash = ir.denom_pub_hash
- )--exists
-SELECT
- exists.existed AS existed1,
- exists.known_coin_id AS known_coin_id1,
- exists.denom_pub_hash AS denom_pub_hash1,
- exists.age_commitment_hash AS age_commitment_hash1,
- (
- SELECT exists.existed
- FROM exists
- WHERE exists.denom_pub_hash = in_denom_pub_hash2
- ) AS existed2,
- (
- SELECT exists.known_coin_id
- FROM exists
- WHERE exists.denom_pub_hash = in_denom_pub_hash2
- ) AS known_coin_id2,
- (
- SELECT exists.denom_pub_hash
- FROM exists
- WHERE exists.denom_pub_hash = in_denom_pub_hash2
- ) AS denom_pub_hash2,
- (
- SELECT exists.age_commitment_hash
- FROM exists
- WHERE exists.denom_pub_hash = in_denom_pub_hash2
- )AS age_commitment_hash2
-FROM exists;
-
-RETURN;
-END $$;
-
-
-CREATE OR REPLACE FUNCTION exchange_do_batch1_known_coin(
- IN in_coin_pub1 BYTEA,
- IN in_denom_pub_hash1 BYTEA,
- IN in_h_age_commitment1 BYTEA,
- IN in_denom_sig1 BYTEA,
- OUT existed1 BOOLEAN,
- OUT known_coin_id1 INT8,
- OUT denom_pub_hash1 BYTEA,
- OUT age_commitment_hash1 BYTEA)
-LANGUAGE plpgsql
-AS $$
-BEGIN
-WITH dd AS (
-SELECT
- denominations_serial,
- coin
- FROM denominations
- WHERE denom_pub_hash
- IN
- (in_denom_pub_hash1,
- in_denom_pub_hash2)
- ),--dd
- input_rows AS (
- VALUES
- (in_coin_pub1,
- in_denom_pub_hash1,
- in_h_age_commitment1,
- in_denom_sig1)
- ),--ir
- ins AS (
- INSERT INTO known_coins (
- coin_pub,
- denominations_serial,
- age_commitment_hash,
- denom_sig,
- remaining
- )
- SELECT
- ir.coin_pub,
- dd.denominations_serial,
- ir.age_commitment_hash,
- ir.denom_sig,
- dd.coin
- FROM input_rows ir
- JOIN dd
- ON dd.denom_pub_hash = ir.denom_pub_hash
- ON CONFLICT DO NOTHING
- RETURNING known_coin_id
- ),--kc
- exists AS (
- SELECT
- CASE
- WHEN ins.known_coin_id IS NOT NULL
- THEN
- FALSE
- ELSE
- TRUE
- END AS existed,
- ins.known_coin_id,
- dd.denom_pub_hash,
- kc.age_commitment_hash
- FROM input_rows ir
- LEFT JOIN ins
- ON ins.coin_pub = ir.coin_pub
- LEFT JOIN known_coins kc
- ON kc.coin_pub = ir.coin_pub
- LEFT JOIN dd
- ON dd.denom_pub_hash = ir.denom_pub_hash
- )--exists
-SELECT
- exists.existed AS existed1,
- exists.known_coin_id AS known_coin_id1,
- exists.denom_pub_hash AS denom_pub_hash1,
- exists.age_commitment_hash AS age_commitment_hash1
-FROM exists;
-
-RETURN;
-END $$;
-
-/*** Experiment using a loop ***/
-/*
-CREATE OR REPLACE FUNCTION exchange_do_batch2_known_coin(
- IN in_coin_pub1 BYTEA,
- IN in_denom_pub_hash1 TEXT,
- IN in_h_age_commitment1 TEXT,
- IN in_denom_sig1 TEXT,
- IN in_coin_pub2 BYTEA,
- IN in_denom_pub_hash2 TEXT,
- IN in_h_age_commitment2 TEXT,
- IN in_denom_sig2 TEXT,
- OUT existed1 BOOLEAN,
- OUT existed2 BOOLEAN,
- OUT known_coin_id1 INT8,
- OUT known_coin_id2 INT8,
- OUT denom_pub_hash1 TEXT,
- OUT denom_pub_hash2 TEXT,
- OUT age_commitment_hash1 TEXT,
- OUT age_commitment_hash2 TEXT)
-LANGUAGE plpgsql
-AS $$
-DECLARE
- ins_values RECORD;
-BEGIN
- FOR i IN 1..2 LOOP
- ins_values := (
- SELECT
- in_coin_pub1 AS coin_pub,
- in_denom_pub_hash1 AS denom_pub_hash,
- in_h_age_commitment1 AS age_commitment_hash,
- in_denom_sig1 AS denom_sig
- WHERE i = 1
- UNION
- SELECT
- in_coin_pub2 AS coin_pub,
- in_denom_pub_hash2 AS denom_pub_hash,
- in_h_age_commitment2 AS age_commitment_hash,
- in_denom_sig2 AS denom_sig
- WHERE i = 2
- );
- WITH dd (denominations_serial, coin) AS (
- SELECT denominations_serial, coin
- FROM denominations
- WHERE denom_pub_hash = ins_values.denom_pub_hash
- ),
- input_rows(coin_pub) AS (
- VALUES (ins_values.coin_pub)
- ),
- ins AS (
- INSERT INTO known_coins (
- coin_pub,
- denominations_serial,
- age_commitment_hash,
- denom_sig,
- remaining
- ) SELECT
- input_rows.coin_pub,
- dd.denominations_serial,
- ins_values.age_commitment_hash,
- ins_values.denom_sig,
- coin
- FROM dd
- CROSS JOIN input_rows
- ON CONFLICT DO NOTHING
- RETURNING known_coin_id, denom_pub_hash
- )
- SELECT
- CASE i
- WHEN 1 THEN
- COALESCE(ins.known_coin_id, 0) <> 0 AS existed1,
- ins.known_coin_id AS known_coin_id1,
- ins.denom_pub_hash AS denom_pub_hash1,
- ins.age_commitment_hash AS age_commitment_hash1
- WHEN 2 THEN
- COALESCE(ins.known_coin_id, 0) <> 0 AS existed2,
- ins.known_coin_id AS known_coin_id2,
- ins.denom_pub_hash AS denom_pub_hash2,
- ins.age_commitment_hash AS age_commitment_hash2
- END
- FROM ins;
- END LOOP;
-END;
-$$;*/
diff --git a/src/exchangedb/do_refresh.sql b/src/exchangedb/do_refresh.sql
@@ -77,10 +77,11 @@ out_coin_found = TRUE;
out_coin_balance = known_coin.remaining;
-- Next, check for idempotency
-SELECT TRUE, noreveal_index
-INTO out_idempotent, out_noreveal_index
-FROM exchange.refresh
-WHERE rc=in_rc;
+SELECT noreveal_index
+ INTO out_noreveal_index
+ FROM exchange.refresh
+ WHERE rc=in_rc;
+out_idempotent = FOUND;
IF out_idempotent
THEN
@@ -91,7 +92,7 @@ THEN
out_balance_ok = TRUE;
out_zombie_bad = FALSE; -- zombie is OK
out_nonce_reuse = FALSE;
-RETURN;
+ RETURN;
END IF;
out_idempotent = FALSE;
diff --git a/src/exchangedb/gc.sql b/src/exchangedb/gc.sql
@@ -92,15 +92,15 @@ DELETE FROM denominations
(SELECT DISTINCT coin_pub
FROM recoup_refresh));
-DELETE FROM recoup_refresh
- WHERE known_coin_id < coin_min;
-
SELECT known_coin_id
INTO coin_min
FROM known_coins
ORDER BY known_coin_id ASC
LIMIT 1;
+DELETE FROM recoup_refresh
+ WHERE known_coin_id < coin_min;
+
SELECT batch_deposit_serial_id
INTO batch_deposit_min
FROM coin_deposits
diff --git a/src/exchangedb/meson.build b/src/exchangedb/meson.build
@@ -55,7 +55,6 @@ libtalerexchangedb = library(
'add_denomination_key.c',
'add_policy_fulfillment_proof.c',
'aggregate.c',
- 'batch_ensure_coin_known.c',
'begin_revolving_shard.c',
'begin_shard.c',
'pg.c',
diff --git a/src/exchangedb/persist_policy_details.sql b/src/exchangedb/persist_policy_details.sql
@@ -94,7 +94,7 @@ BEGIN
-- Set the fulfillment_state according to the values.
-- For now, we only update the state when it was INSUFFICIENT.
-- FIXME[oec] #7999: What to do in case of Failure or other state?
- IF (out_fullfillment_state = 2) -- INSUFFICIENT
+ IF (out_fulfillment_state = 2) -- INSUFFICIENT
THEN
IF (out_accumulated_total.val >= cur_commitment.val OR
(out_accumulated_total.val = cur_commitment.val AND
diff --git a/src/exchangedb/select_aggregations_above_serial.sql b/src/exchangedb/select_aggregations_above_serial.sql
@@ -53,6 +53,11 @@ LOOP
my_batch_record
FROM coin_deposits cdep
WHERE cdep.batch_deposit_serial_id = i.batch_deposit_serial_id;
+ IF NOT FOUND
+ THEN
+ -- No matching deposit found, how can this be!?
+ RETURN;
+ END IF;
my_total_val=my_batch_record.total_val;
my_total_frac=my_batch_record.total_frac;
diff --git a/src/exchangedb/sql-schema/exchange_statistics_helpers.sql b/src/exchangedb/sql-schema/exchange_statistics_helpers.sql
@@ -921,7 +921,7 @@ BEGIN
WHERE imeta_serial_id=my_meta
AND h_payto=my_h_payto
AND slot >= my_time - max_slot
- AND slot < my_time - max_slot;
+ AND slot < my_time - min_slot;
-- we only proceed if we had more then one match (optimization)
IF FOUND AND my_sum.matches > 1
THEN
@@ -934,11 +934,11 @@ BEGIN
WHERE imeta_serial_id=my_meta
AND h_payto=my_h_payto
AND slot >= my_time - max_slot
- AND slot < my_time - max_slot
+ AND slot < my_time - min_slot
AND aevent_serial_id > my_sum.rep_serial_id;
-- Now update the representative to the sum
UPDATE exchange_statistic_amount_event SET
- delta.val = my_total_value
+ delta.val = my_total_val
,delta.frac = my_total_frac
WHERE imeta_serial_id = my_meta
AND h_payto = my_h_payto
@@ -987,12 +987,12 @@ BEGIN
DELETE
FROM exchange_statistic_bucket_amount
WHERE bmeta_serial_id = my_rec.bmeta_serial_id
- AND bucket_start >= my_end;
+ AND bucket_start < my_end;
ELSE
DELETE
FROM exchange_statistic_bucket_counter
WHERE bmeta_serial_id = my_rec.bmeta_serial_id
- AND bucket_start >= my_end;
+ AND bucket_start < my_end;
END IF;
END LOOP;
END $$;
diff --git a/src/exchangedb/sql-schema/meson.build b/src/exchangedb/sql-schema/meson.build
@@ -36,7 +36,6 @@ procedures_sql = [
'../reserves_in_insert.sql',
# semi-dead...
'exchange_do_get_link_data.sql',
- '../batch_ensure_coin_known.sql',
'../kycauth_in_insert.sql',
'../trigger_kyc_rule_for_account.sql',
'../lookup_kyc_requirement_by_row.sql',
@@ -191,4 +190,3 @@ foreach g : generated_sql
install_dir: sqldir,
)
endforeach
-