diff options
Diffstat (limited to 'src/exchangedb/exchange-0001.sql')
-rw-r--r-- | src/exchangedb/exchange-0001.sql | 220 |
1 files changed, 157 insertions, 63 deletions
diff --git a/src/exchangedb/exchange-0001.sql b/src/exchangedb/exchange-0001.sql index df07e0252..3f9979c06 100644 --- a/src/exchangedb/exchange-0001.sql +++ b/src/exchangedb/exchange-0001.sql @@ -1,6 +1,6 @@ -- -- This file is part of TALER --- Copyright (C) 2014--2021 Taler Systems SA +-- 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 @@ -22,7 +22,7 @@ SELECT _v.register_patch('exchange-0001', NULL, NULL); CREATE TABLE IF NOT EXISTS denominations - (denominations_serial BIGSERIAL UNIQUE + (denominations_serial BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE ,denom_pub_hash BYTEA PRIMARY KEY CHECK (LENGTH(denom_pub_hash)=64) ,denom_type INT4 NOT NULL DEFAULT (1) -- 1 == RSA (for now, remove default later!) ,age_mask INT4 NOT NULL DEFAULT (0) @@ -58,7 +58,7 @@ CREATE INDEX IF NOT EXISTS denominations_by_expire_legal_index CREATE TABLE IF NOT EXISTS denomination_revocations - (denom_revocations_serial_id BIGSERIAL UNIQUE + (denom_revocations_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE ,denominations_serial INT8 PRIMARY KEY REFERENCES denominations (denominations_serial) ON DELETE CASCADE ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64) ); @@ -67,7 +67,7 @@ COMMENT ON TABLE denomination_revocations CREATE TABLE IF NOT EXISTS wire_targets - (wire_target_serial_id BIGSERIAL -- UNIQUE + (wire_target_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY -- UNIQUE ,h_payto BYTEA PRIMARY KEY CHECK (LENGTH(h_payto)=64) ,payto_uri VARCHAR NOT NULL ,kyc_ok BOOLEAN NOT NULL DEFAULT (FALSE) @@ -89,7 +89,7 @@ CREATE TABLE IF NOT EXISTS wire_targets_default FOR VALUES WITH (MODULUS 1, REMAINDER 0); CREATE TABLE IF NOT EXISTS reserves - (reserve_uuid BIGSERIAL + (reserve_uuid BIGINT GENERATED BY DEFAULT AS IDENTITY ,reserve_pub BYTEA PRIMARY KEY CHECK(LENGTH(reserve_pub)=32) ,current_balance_val INT8 NOT NULL ,current_balance_frac INT4 NOT NULL @@ -130,7 +130,7 @@ COMMENT ON INDEX reserves_by_gc_date_index CREATE TABLE IF NOT EXISTS reserves_in - (reserve_in_serial_id BIGSERIAL -- UNIQUE + (reserve_in_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY -- UNIQUE ,reserve_pub BYTEA PRIMARY KEY REFERENCES reserves (reserve_pub) ON DELETE CASCADE ,wire_reference INT8 NOT NULL ,credit_val INT8 NOT NULL @@ -168,7 +168,7 @@ CREATE INDEX IF NOT EXISTS reserves_in_by_exchange_account_reserve_in_serial_id_ CREATE TABLE IF NOT EXISTS reserves_close - (close_uuid BIGSERIAL -- UNIQUE / PRIMARY KEY + (close_uuid BIGINT GENERATED BY DEFAULT AS IDENTITY -- UNIQUE / PRIMARY KEY ,reserve_pub BYTEA NOT NULL REFERENCES reserves (reserve_pub) ON DELETE CASCADE ,execution_date INT8 NOT NULL ,wtid BYTEA NOT NULL CHECK (LENGTH(wtid)=32) @@ -195,8 +195,7 @@ CREATE INDEX IF NOT EXISTS reserves_close_by_reserve_pub_index CREATE TABLE IF NOT EXISTS reserves_out - (reserve_out_serial_id BIGSERIAL -- UNIQUE - ,wih BYTEA PRIMARY KEY CHECK (LENGTH(wih)=64) + (reserve_out_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY -- UNIQUE ,h_blind_ev BYTEA CHECK (LENGTH(h_blind_ev)=64) -- UNIQUE ,denominations_serial INT8 NOT NULL REFERENCES denominations (denominations_serial) ,denom_sig BYTEA NOT NULL @@ -206,11 +205,9 @@ CREATE TABLE IF NOT EXISTS reserves_out ,amount_with_fee_val INT8 NOT NULL ,amount_with_fee_frac INT4 NOT NULL ) - PARTITION BY HASH (wih); + PARTITION BY HASH (h_blind_ev); COMMENT ON TABLE reserves_out IS 'Withdraw operations performed on reserves.'; -COMMENT ON COLUMN reserves_out.wih - IS 'Hash that uniquely identifies the withdraw request. Used to detect request replays (crucial for CS) and to check the withdraw existed during recoup.'; COMMENT ON COLUMN reserves_out.h_blind_ev IS 'Hash of the blinded coin, used as primary key here so that broken clients that use a non-random coin or blinding factor fail to withdraw (otherwise they would fail on deposit when the coin is not unique there).'; COMMENT ON COLUMN reserves_out.denominations_serial @@ -230,7 +227,7 @@ COMMENT ON INDEX reserves_out_by_reserve_uuid_and_execution_date_index CREATE TABLE IF NOT EXISTS auditors - (auditor_uuid BIGSERIAL UNIQUE + (auditor_uuid BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE ,auditor_pub BYTEA PRIMARY KEY CHECK (LENGTH(auditor_pub)=32) ,auditor_name VARCHAR NOT NULL ,auditor_url VARCHAR NOT NULL @@ -250,7 +247,7 @@ COMMENT ON COLUMN auditors.last_change CREATE TABLE IF NOT EXISTS auditor_denom_sigs - (auditor_denom_serial BIGSERIAL UNIQUE + (auditor_denom_serial BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE ,auditor_uuid INT8 NOT NULL REFERENCES auditors (auditor_uuid) ON DELETE CASCADE ,denominations_serial INT8 NOT NULL REFERENCES denominations (denominations_serial) ON DELETE CASCADE ,auditor_sig BYTEA CHECK (LENGTH(auditor_sig)=64) @@ -267,7 +264,7 @@ COMMENT ON COLUMN auditor_denom_sigs.auditor_sig CREATE TABLE IF NOT EXISTS exchange_sign_keys - (esk_serial BIGSERIAL UNIQUE + (esk_serial BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE ,exchange_pub BYTEA PRIMARY KEY CHECK (LENGTH(exchange_pub)=32) ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64) ,valid_from INT8 NOT NULL @@ -289,7 +286,7 @@ COMMENT ON COLUMN exchange_sign_keys.expire_legal CREATE TABLE IF NOT EXISTS signkey_revocations - (signkey_revocations_serial_id BIGSERIAL UNIQUE + (signkey_revocations_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE ,esk_serial INT8 PRIMARY KEY REFERENCES exchange_sign_keys (esk_serial) ON DELETE CASCADE ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64) ); @@ -298,7 +295,7 @@ COMMENT ON TABLE signkey_revocations CREATE TABLE IF NOT EXISTS extensions - (extension_id BIGSERIAL UNIQUE + (extension_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE ,name VARCHAR NOT NULL UNIQUE ,config BYTEA ); @@ -311,7 +308,7 @@ COMMENT ON COLUMN extensions.config CREATE TABLE IF NOT EXISTS known_coins - (known_coin_id BIGSERIAL -- UNIQUE + (known_coin_id BIGINT GENERATED BY DEFAULT AS IDENTITY -- UNIQUE ,denominations_serial INT8 NOT NULL REFERENCES denominations (denominations_serial) ON DELETE CASCADE ,coin_pub BYTEA NOT NULL PRIMARY KEY CHECK (LENGTH(coin_pub)=32) ,age_hash BYTEA CHECK (LENGTH(age_hash)=32) @@ -342,7 +339,7 @@ CREATE INDEX IF NOT EXISTS known_coins_by_known_coin_id_index CREATE TABLE IF NOT EXISTS refresh_commitments - (melt_serial_id BIGSERIAL -- UNIQUE + (melt_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY -- UNIQUE ,rc BYTEA PRIMARY KEY CHECK (LENGTH(rc)=64) ,old_coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub) ON DELETE CASCADE ,h_age_commitment BYTEA CHECK(LENGTH(h_age_commitment)=32) @@ -375,7 +372,7 @@ CREATE INDEX IF NOT EXISTS refresh_commitments_by_old_coin_pub_index CREATE TABLE IF NOT EXISTS refresh_revealed_coins - (rrc_serial BIGSERIAL -- UNIQUE + (rrc_serial BIGINT GENERATED BY DEFAULT AS IDENTITY -- UNIQUE ,melt_serial_id INT8 NOT NULL -- REFERENCES refresh_commitments (melt_serial_id) ON DELETE CASCADE ,freshcoin_index INT4 NOT NULL ,link_sig BYTEA NOT NULL CHECK(LENGTH(link_sig)=64) @@ -419,7 +416,7 @@ CREATE INDEX IF NOT EXISTS refresh_revealed_coins_by_melt_serial_id_index CREATE TABLE IF NOT EXISTS refresh_transfer_keys - (rtc_serial BIGSERIAL -- UNIQUE + (rtc_serial BIGINT GENERATED BY DEFAULT AS IDENTITY -- UNIQUE ,melt_serial_id INT8 PRIMARY KEY -- REFERENCES refresh_commitments (melt_serial_id) ON DELETE CASCADE ,transfer_pub BYTEA NOT NULL CHECK(LENGTH(transfer_pub)=32) ,transfer_privs BYTEA NOT NULL @@ -445,7 +442,7 @@ CREATE INDEX IF NOT EXISTS refresh_transfer_keys_by_rtc_serial_index CREATE TABLE IF NOT EXISTS extension_details - (extension_details_serial_id BIGSERIAL PRIMARY KEY + (extension_details_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY ,extension_options VARCHAR); COMMENT ON TABLE extension_details IS 'Extensions that were provided with deposits (not yet used).'; @@ -454,7 +451,7 @@ COMMENT ON COLUMN extension_details.extension_options CREATE TABLE IF NOT EXISTS deposits - (deposit_serial_id BIGSERIAL -- PRIMARY KEY + (deposit_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY -- PRIMARY KEY ,shard INT8 NOT NULL ,known_coin_id INT8 NOT NULL -- REFERENCES known_coins (known_coin_id) ON DELETE CASCADE ,amount_with_fee_val INT8 NOT NULL @@ -526,7 +523,7 @@ COMMENT ON INDEX deposits_for_iterate_matching_index CREATE TABLE IF NOT EXISTS refunds - (refund_serial_id BIGSERIAL -- UNIQUE + (refund_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY -- UNIQUE ,deposit_serial_id INT8 NOT NULL -- REFERENCES deposits (deposit_serial_id) ON DELETE CASCADE ,merchant_sig BYTEA NOT NULL CHECK(LENGTH(merchant_sig)=64) ,rtransaction_id INT8 NOT NULL @@ -553,7 +550,7 @@ CREATE INDEX IF NOT EXISTS refunds_by_refund_serial_id_index CREATE TABLE IF NOT EXISTS wire_out - (wireout_uuid BIGSERIAL -- PRIMARY KEY + (wireout_uuid BIGINT GENERATED BY DEFAULT AS IDENTITY -- PRIMARY KEY ,execution_date INT8 NOT NULL ,wtid_raw BYTEA UNIQUE NOT NULL CHECK (LENGTH(wtid_raw)=32) ,wire_target_serial_id INT8 NOT NULL -- REFERENCES wire_targets (wire_target_serial_id) @@ -582,7 +579,7 @@ CREATE INDEX IF NOT EXISTS wire_out_by_wire_target_serial_id_index CREATE TABLE IF NOT EXISTS aggregation_tracking - (aggregation_serial_id BIGSERIAL -- UNIQUE + (aggregation_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY -- UNIQUE ,deposit_serial_id INT8 PRIMARY KEY -- REFERENCES deposits (deposit_serial_id) ON DELETE CASCADE ,wtid_raw BYTEA CONSTRAINT wire_out_ref REFERENCES wire_out(wtid_raw) ON DELETE CASCADE DEFERRABLE ) @@ -606,7 +603,7 @@ COMMENT ON INDEX aggregation_tracking_by_wtid_raw_index CREATE TABLE IF NOT EXISTS wire_fee - (wire_fee_serial BIGSERIAL UNIQUE + (wire_fee_serial BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE ,wire_method VARCHAR NOT NULL ,start_date INT8 NOT NULL ,end_date INT8 NOT NULL @@ -628,7 +625,7 @@ CREATE INDEX IF NOT EXISTS wire_fee_by_end_date_index CREATE TABLE IF NOT EXISTS recoup - (recoup_uuid BIGSERIAL -- UNIQUE + (recoup_uuid BIGINT GENERATED BY DEFAULT AS IDENTITY -- UNIQUE ,known_coin_id INT8 NOT NULL -- REFERENCES known_coins (known_coin_id) ,coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64) ,coin_blind BYTEA NOT NULL CHECK(LENGTH(coin_blind)=32) @@ -643,7 +640,7 @@ COMMENT ON TABLE recoup COMMENT ON COLUMN recoup.known_coin_id IS 'Coin that is being debited in the recoup. Do not CASCADE ON DROP on the coin_pub, as we may keep the coin alive!'; COMMENT ON COLUMN recoup.reserve_out_serial_id - IS 'Identifies the wih of the recouped coin and provides the link to the credited reserve.'; + IS 'Identifies the h_blind_ev of the recouped coin and provides the link to the credited reserve.'; COMMENT ON COLUMN recoup.coin_sig IS 'Signature by the coin affirming the recoup, of type TALER_SIGNATURE_WALLET_COIN_RECOUP'; COMMENT ON COLUMN recoup.coin_blind @@ -664,7 +661,7 @@ CREATE INDEX IF NOT EXISTS recoup_by_known_coin_id_index CREATE TABLE IF NOT EXISTS recoup_refresh - (recoup_refresh_uuid BIGSERIAL -- UNIQUE + (recoup_refresh_uuid BIGINT GENERATED BY DEFAULT AS IDENTITY -- UNIQUE ,known_coin_id INT8 NOT NULL -- REFERENCES known_coins (known_coin_id) ,coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64) ,coin_blind BYTEA NOT NULL CHECK(LENGTH(coin_blind)=32) @@ -698,7 +695,7 @@ CREATE INDEX IF NOT EXISTS recoup_refresh_by_known_coin_id_index CREATE TABLE IF NOT EXISTS prewire - (prewire_uuid BIGSERIAL PRIMARY KEY + (prewire_uuid BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY ,wire_method TEXT NOT NULL ,finished BOOLEAN NOT NULL DEFAULT false ,failed BOOLEAN NOT NULL DEFAULT false @@ -746,12 +743,29 @@ COMMENT ON COLUMN wire_accounts.is_active IS 'true if we are currently supporting the use of this account.'; COMMENT ON COLUMN wire_accounts.last_change IS 'Latest time when active status changed. Used to detect replays of old messages.'; --- "wire_accounts" has no BIGSERIAL because it is a 'mutable' table +-- "wire_accounts" has no sequence because it is a 'mutable' table -- and is of no concern to the auditor +CREATE TABLE IF NOT EXISTS cs_nonce_locks + (cs_nonce_lock_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY -- UNIQUE + ,nonce BYTEA PRIMARY KEY CHECK (LENGTH(nonce)=32) + ,op_hash BYTEA NOT NULL CHECK (LENGTH(op_hash)=64) + ,max_denomination_serial INT8 NOT NULL + ) + PARTITION BY HASH (nonce); +COMMENT ON TABLE cs_nonce_locks + IS 'ensures a Clause Schnorr client nonce is locked for use with an operation identified by a hash'; +COMMENT ON COLUMN cs_nonce_locks.nonce + IS 'actual nonce submitted by the client'; +COMMENT ON COLUMN cs_nonce_locks.op_hash + IS 'hash (RC for refresh, blind coin hash for withdraw) the nonce may be used with'; +COMMENT ON COLUMN cs_nonce_locks.max_denomination_serial + IS 'Maximum number of a CS denomination serial the nonce could be used with, for GC'; + + CREATE TABLE IF NOT EXISTS work_shards - (shard_serial_id BIGSERIAL UNIQUE + (shard_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE ,last_attempt INT8 NOT NULL ,start_row INT8 NOT NULL ,end_row INT8 NOT NULL @@ -783,7 +797,7 @@ CREATE INDEX IF NOT EXISTS work_shards_by_job_name_completed_last_attempt_index CREATE UNLOGGED TABLE IF NOT EXISTS revolving_work_shards - (shard_serial_id BIGSERIAL UNIQUE + (shard_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE ,last_attempt INT8 NOT NULL ,start_row INT4 NOT NULL ,end_row INT4 NOT NULL @@ -818,7 +832,7 @@ CREATE INDEX IF NOT EXISTS revolving_work_shards_by_job_name_active_last_attempt CREATE OR REPLACE FUNCTION exchange_do_withdraw( - IN in_wih BYTEA, + IN cs_nonce BYTEA, IN amount_val INT8, IN amount_frac INT4, IN h_denom_pub BYTEA, @@ -832,8 +846,7 @@ CREATE OR REPLACE FUNCTION exchange_do_withdraw( OUT balance_ok BOOLEAN, OUT kycok BOOLEAN, OUT account_uuid INT8, - OUT ruuid INT8, - OUT out_denom_sig BYTEA) + OUT ruuid INT8) LANGUAGE plpgsql AS $$ DECLARE @@ -851,7 +864,8 @@ BEGIN -- reserves_in by reserve_pub (SELECT) -- wire_targets by wire_target_serial_id -SELECT denominations_serial INTO denom_serial +SELECT denominations_serial + INTO denom_serial FROM denominations WHERE denom_pub_hash=h_denom_pub; @@ -867,6 +881,7 @@ THEN RETURN; END IF; + SELECT current_balance_val ,current_balance_frac @@ -887,7 +902,7 @@ THEN balance_ok=FALSE; kycok=FALSE; account_uuid=0; - ruuid=0; + ruuid=2; RETURN; END IF; @@ -895,7 +910,6 @@ END IF; -- the query successful due to idempotency. INSERT INTO reserves_out (h_blind_ev - ,wih ,denominations_serial ,denom_sig ,reserve_uuid @@ -905,7 +919,6 @@ INSERT INTO reserves_out ,amount_with_fee_frac) VALUES (h_coin_envelope - ,in_wih ,denom_serial ,denom_sig ,ruuid @@ -918,25 +931,6 @@ ON CONFLICT DO NOTHING; IF NOT FOUND THEN -- idempotent query, all constraints must be satisfied - - SELECT - denom_sig - INTO - out_denom_sig - FROM reserves_in - WHERE wih=in_wih - LIMIT 1; -- limit 1 should not be required (without p2p transfers) - - IF NOT FOUND - THEN - reserve_found=FALSE; - balance_ok=FALSE; - kycok=FALSE; - account_uuid=0; - ruuid=0; - ASSERT false, 'internal logic error'; - END IF; - reserve_found=TRUE; balance_ok=TRUE; kycok=TRUE; @@ -983,6 +977,44 @@ WHERE reserve_found=TRUE; balance_ok=TRUE; + + +-- Special actions needed for a CS withdraw? +IF NOT NULL cs_nonce +THEN + -- Cache CS signature to prevent replays in the future + -- (and check if cached signature exists at the same time). + INSERT INTO cs_nonce_locks + (nonce + ,max_denomination_serial + ,op_hash) + VALUES + (cs_nonce + ,denom_serial + ,h_coin_envelope) + ON CONFLICT DO NOTHING; + + IF NOT FOUND + THEN + -- See if the existing entry is identical. + SELECT 1 + FROM cs_nonce_locks + WHERE nonce=cs_nonce + AND op_hash=h_coin_envelope; + IF NOT FOUND + THEN + reserve_found=FALSE; + balance_ok=FALSE; + kycok=FALSE; + account_uuid=0; + ruuid=1; -- FIXME: return error message more nicely! + ASSERT false, 'nonce reuse attempted by client'; + END IF; + END IF; +END IF; + + + -- Obtain KYC status based on the last wire transfer into -- this reserve. FIXME: likely not adequate for reserves that got P2P transfers! SELECT @@ -996,9 +1028,6 @@ SELECT WHERE reserve_pub=rpub LIMIT 1; -- limit 1 should not be required (without p2p transfers) --- Return denomination signature as result that --- was given as the argument. -out_denom_sig=denom_sig; END $$; @@ -1223,6 +1252,7 @@ END $$; CREATE OR REPLACE FUNCTION exchange_do_melt( + IN in_cs_rms BYTEA, IN in_amount_with_fee_val INT8, IN in_amount_with_fee_frac INT4, IN in_rc BYTEA, @@ -1236,6 +1266,8 @@ CREATE OR REPLACE FUNCTION exchange_do_melt( OUT out_noreveal_index INT4) LANGUAGE plpgsql AS $$ +DECLARE + denom_max INT8; BEGIN -- Shards: INSERT refresh_commitments (by rc) -- (rare:) SELECT refresh_commitments (by old_coin_pub) -- crosses shards! @@ -1333,6 +1365,56 @@ THEN RETURN; END IF; + + +-- Special actions needed for a CS melt? +IF NOT NULL in_cs_rms +THEN + -- Get maximum denominations serial value in + -- existence, this will determine how long the + -- nonce will be locked. + SELECT + denominations_serial + INTO + denom_max + FROM denominations + ORDER BY denominations_serial DESC + LIMIT 1; + + -- Cache CS signature to prevent replays in the future + -- (and check if cached signature exists at the same time). + INSERT INTO cs_nonce_locks + (nonce + ,max_denomination_serial + ,op_hash) + VALUES + (cs_rms + ,denom_serial + ,in_rc) + ON CONFLICT DO NOTHING; + + IF NOT FOUND + THEN + -- Record exists, make sure it is the same + SELECT 1 + FROM cs_nonce_locks + WHERE nonce=cs_rms + AND op_hash=in_rc; + + IF NOT FOUND + THEN + -- Nonce reuse detected + out_balance_ok=FALSE; + out_zombie_bad=FALSE; + out_noreveal_index=42; -- FIXME: return error message more nicely! + ASSERT false, 'nonce reuse attempted by client'; + END IF; + END IF; +END IF; + + + + -- Everything fine, return success! out_balance_ok=TRUE; out_noreveal_index=in_noreveal_index; @@ -1806,6 +1888,8 @@ DECLARE deposit_min INT8; -- minimum deposit still alive DECLARE reserve_out_min INT8; -- minimum reserve_out still alive +DECLARE + denom_min INT8; -- minimum denomination still alive BEGIN DELETE FROM prewire @@ -1901,6 +1985,16 @@ DELETE FROM refunds DELETE FROM aggregation_tracking WHERE deposit_serial_id < deposit_min; +SELECT + denominations_serial + INTO + denom_min + FROM denominations + ORDER BY denominations_serial ASC + LIMIT 1; + +DELETE FROM cs_nonce_locks + WHERE max_denomination_serial <= denom_min; END $$; |