taler_amount type introduced in reserves table and corresponding functions

- current_balance is now a taler_amount
- all C-functions, SQL-statements and stored procedures adjusted accordingly.

=> make check passes all tests in testing.
This commit is contained in:
Özgür Kesim 2023-07-28 23:27:02 +02:00
parent a1dae0199f
commit 6dedca0fa3
Signed by: oec
GPG Key ID: 3D76A56D79EDD9D7
18 changed files with 227 additions and 224 deletions

View File

@ -36,10 +36,9 @@ CREATE OR REPLACE FUNCTION exchange_do_age_withdraw(
LANGUAGE plpgsql LANGUAGE plpgsql
AS $$ AS $$
DECLARE DECLARE
reserve_gc INT8; reserve RECORD;
difference RECORD; difference RECORD;
balance taler_amount; balance taler_amount;
new_balance taler_amount;
not_before date; not_before date;
earliest_date date; earliest_date date;
BEGIN BEGIN
@ -49,15 +48,8 @@ BEGIN
-- reserves_in by reserve_pub (SELECT) -- reserves_in by reserve_pub (SELECT)
-- wire_targets by wire_target_h_payto -- wire_targets by wire_target_h_payto
SELECT SELECT *
current_balance INTO reserve
,gc_date
,birthday
INTO
balance.val
,balance.frac
,reserve_gc
,reserve_birthday
FROM exchange.reserves FROM exchange.reserves
WHERE reserves.reserve_pub=rpub; WHERE reserves.reserve_pub=rpub;
@ -74,10 +66,13 @@ END IF;
reserve_found = TRUE; reserve_found = TRUE;
conflict=FALSE; -- not really yet determined conflict=FALSE; -- not really yet determined
balance = reserve.current_balance;
reserve_birthday = reserve.birthday;
-- Check age requirements -- Check age requirements
IF (reserve_birthday <> 0) IF (reserve.birthday <> 0)
THEN THEN
not_before=date '1970-01-01' + reserve_birthday; not_before=date '1970-01-01' + reserve.birthday;
earliest_date = current_date - make_interval(maximum_age_committed); earliest_date = current_date - make_interval(maximum_age_committed);
-- --
-- 1970-01-01 + birthday == not_before now -- 1970-01-01 + birthday == not_before now
@ -103,11 +98,8 @@ required_age=0;
-- Check reserve balance is sufficient. -- Check reserve balance is sufficient.
SELECT * SELECT *
INTO INTO difference
difference FROM amount_left_minus_right(balance
FROM
amount_left_minus_right(
balance
,amount_with_fee); ,amount_with_fee);
balance_ok = difference.ok; balance_ok = difference.ok;
@ -117,15 +109,15 @@ THEN
RETURN; RETURN;
END IF; END IF;
new_balance = difference.diff; balance = difference.diff;
-- Calculate new expiration dates. -- Calculate new expiration dates.
min_reserve_gc=GREATEST(min_reserve_gc,reserve_gc); min_reserve_gc=GREATEST(min_reserve_gc,reserve.gc_date);
-- Update reserve balance. -- Update reserve balance.
UPDATE reserves SET UPDATE reserves SET
gc_date=min_reserve_gc gc_date=min_reserve_gc
,current_balance=new_balance ,current_balance=balance
WHERE WHERE
reserves.reserve_pub=rpub; reserves.reserve_pub=rpub;

View File

@ -30,9 +30,8 @@ CREATE OR REPLACE FUNCTION exchange_do_batch_withdraw(
LANGUAGE plpgsql LANGUAGE plpgsql
AS $$ AS $$
DECLARE DECLARE
reserve_gc INT8; reserve RECORD;
reserve taler_amount; balance taler_amount;
reserve_birthday INT4;
not_before date; not_before date;
BEGIN BEGIN
-- Shards: reserves by reserve_pub (SELECT) -- Shards: reserves by reserve_pub (SELECT)
@ -42,18 +41,8 @@ BEGIN
-- wire_targets by wire_target_h_payto -- wire_targets by wire_target_h_payto
SELECT SELECT *
current_balance.val INTO reserve
,current_balance.frac
,gc_date
,birthday
,reserve_uuid
INTO
reserve.val
,reserve.frac
,reserve_gc
,reserve_birthday
,ruuid
FROM exchange.reserves FROM exchange.reserves
WHERE reserves.reserve_pub=rpub; WHERE reserves.reserve_pub=rpub;
@ -68,9 +57,10 @@ THEN
RETURN; RETURN;
END IF; END IF;
ruuid = reserve.reserve_uuid;
-- Check if age requirements are present -- Check if age requirements are present
IF ((NOT do_age_check) OR (reserve_birthday = 0)) IF ((NOT do_age_check) OR (reserve.birthday = 0))
THEN THEN
age_ok = TRUE; age_ok = TRUE;
allowed_maximum_age = -1; allowed_maximum_age = -1;
@ -80,7 +70,7 @@ ELSE
-- birthday set (reserve_birthday != 0), but the client called the -- birthday set (reserve_birthday != 0), but the client called the
-- batch-withdraw endpoint instead of the age-withdraw endpoint, which it -- batch-withdraw endpoint instead of the age-withdraw endpoint, which it
-- should have. -- should have.
not_before=date '1970-01-01' + reserve_birthday; not_before=date '1970-01-01' + reserve.birthday;
allowed_maximum_age = extract(year from age(current_date, not_before)); allowed_maximum_age = extract(year from age(current_date, not_before));
reserve_found=TRUE; reserve_found=TRUE;
@ -89,22 +79,24 @@ ELSE
RETURN; RETURN;
END IF; END IF;
balance = reserve.current_balance;
-- Check reserve balance is sufficient. -- Check reserve balance is sufficient.
IF (reserve.val > amount.val) IF (balance.val > amount.val)
THEN THEN
IF (reserve.frac >= amount.frac) IF (balance.frac >= amount.frac)
THEN THEN
reserve.val=reserve.val - amount.val; balance.val=balance.val - amount.val;
reserve.frac=reserve.frac - amount.frac; balance.frac=balance.frac - amount.frac;
ELSE ELSE
reserve.val=reserve.val - amount.val - 1; balance.val=balance.val - amount.val - 1;
reserve.frac=reserve.frac + 100000000 - amount.frac; balance.frac=balance.frac + 100000000 - amount.frac;
END IF; END IF;
ELSE ELSE
IF (reserve.val = amount.val) AND (reserve.frac >= amount.frac) IF (balance.val = amount.val) AND (balance.frac >= amount.frac)
THEN THEN
reserve.val=0; balance.val=0;
reserve.frac=reserve.frac - amount.frac; balance.frac=balance.frac - amount.frac;
ELSE ELSE
balance_ok=FALSE; balance_ok=FALSE;
RETURN; RETURN;
@ -112,12 +104,12 @@ ELSE
END IF; END IF;
-- Calculate new expiration dates. -- Calculate new expiration dates.
min_reserve_gc=GREATEST(min_reserve_gc,reserve_gc); min_reserve_gc=GREATEST(min_reserve_gc,reserve.gc_date);
-- Update reserve balance. -- Update reserve balance.
UPDATE reserves SET UPDATE reserves SET
gc_date=min_reserve_gc gc_date=min_reserve_gc
,current_balance=reserve ,current_balance=balance
WHERE WHERE
reserves.reserve_pub=rpub; reserves.reserve_pub=rpub;

View File

@ -16,8 +16,7 @@
CREATE OR REPLACE FUNCTION exchange_do_batch_withdraw_insert( CREATE OR REPLACE FUNCTION exchange_do_batch_withdraw_insert(
IN cs_nonce BYTEA, IN cs_nonce BYTEA,
IN amount_val INT8, IN amount taler_amount,
IN amount_frac INT4,
IN h_denom_pub BYTEA, -- FIXME: denom_serials should really be a parameter to this FUNCTION. IN h_denom_pub BYTEA, -- FIXME: denom_serials should really be a parameter to this FUNCTION.
IN ruuid INT8, IN ruuid INT8,
IN reserve_sig BYTEA, IN reserve_sig BYTEA,
@ -74,8 +73,8 @@ VALUES
,ruuid ,ruuid
,reserve_sig ,reserve_sig
,now ,now
,amount_val ,amount.val
,amount_frac) ,amount.frac)
ON CONFLICT DO NOTHING; ON CONFLICT DO NOTHING;
IF NOT FOUND IF NOT FOUND
@ -119,6 +118,6 @@ END IF;
END $$; END $$;
COMMENT ON FUNCTION exchange_do_batch_withdraw_insert(BYTEA, INT8, INT4, BYTEA, INT8, BYTEA, BYTEA, BYTEA, INT8) COMMENT ON FUNCTION exchange_do_batch_withdraw_insert(BYTEA, taler_amount, BYTEA, INT8, BYTEA, BYTEA, BYTEA, INT8)
IS 'Stores information about a planchet for a batch withdraw operation. Checks if the planchet already exists, and in that case indicates a conflict'; IS 'Stores information about a planchet for a batch withdraw operation. Checks if the planchet already exists, and in that case indicates a conflict';

View File

@ -37,8 +37,7 @@ DELETE FROM exchange.wire_fee
-- TODO: use closing fee as threshold? -- TODO: use closing fee as threshold?
DELETE FROM exchange.reserves DELETE FROM exchange.reserves
WHERE gc_date < in_now WHERE gc_date < in_now
AND current_balance.val = 0 AND current_balance = (0, 0);
AND current_balance.frac = 0;
SELECT SELECT
reserve_out_serial_id reserve_out_serial_id

View File

@ -19,12 +19,15 @@ CREATE OR REPLACE FUNCTION exchange_do_history_request(
IN in_reserve_pub BYTEA, IN in_reserve_pub BYTEA,
IN in_reserve_sig BYTEA, IN in_reserve_sig BYTEA,
IN in_request_timestamp INT8, IN in_request_timestamp INT8,
IN in_history_fee_val INT8, IN in_history_fee taler_amount,
IN in_history_fee_frac INT4,
OUT out_balance_ok BOOLEAN, OUT out_balance_ok BOOLEAN,
OUT out_idempotent BOOLEAN) OUT out_idempotent BOOLEAN)
LANGUAGE plpgsql LANGUAGE plpgsql
AS $$ AS $$
DECLARE
reserve RECORD;
balance taler_amount;
new_balance taler_amount;
BEGIN BEGIN
-- Insert and check for idempotency. -- Insert and check for idempotency.
@ -38,8 +41,8 @@ BEGIN
(in_reserve_pub (in_reserve_pub
,in_request_timestamp ,in_request_timestamp
,in_reserve_sig ,in_reserve_sig
,in_history_fee_val ,in_history_fee.val
,in_history_fee_frac) ,in_history_fee.frac)
ON CONFLICT DO NOTHING; ON CONFLICT DO NOTHING;
IF NOT FOUND IF NOT FOUND
@ -51,35 +54,51 @@ BEGIN
out_idempotent=FALSE; out_idempotent=FALSE;
-- Update reserve balance. SELECT *
UPDATE exchange.reserves INTO reserve
SET FROM exchange.reserves
current_balance.frac=current_balance.frac-in_history_fee_frac WHERE reserve_pub=in_reserve_pub;
+ CASE
WHEN current_balance.frac < in_history_fee_frac
THEN 100000000
ELSE 0
END,
current_balance.val=current_balance.val-in_history_fee_val
- CASE
WHEN current_balance.frac < in_history_fee_frac
THEN 1
ELSE 0
END
WHERE
reserve_pub=in_reserve_pub
AND ( (current_balance.val > in_history_fee_val) OR
( (current_balance.frac >= in_history_fee_frac) AND
(current_balance.val >= in_history_fee_val) ) );
IF NOT FOUND IF NOT FOUND
THEN THEN
-- Either reserve does not exist, or balance insufficient. -- Reserve does not exist, we treat it the same here
-- Both we treat the same here as balance insufficient. -- as balance insufficient.
out_balance_ok=FALSE; out_balance_ok=FALSE;
RETURN; RETURN;
END IF; END IF;
balance = reserve.current_balance;
-- check balance
IF ( (balance.val <= in_history_fee.val) AND
( (balance.frac < in_history_fee.frac) OR
(balance.val < in_history_fee.val) ) )
THEN
out_balance_ok=FALSE;
RETURN;
END IF;
new_balance.frac=balance.frac-in_history_fee.frac
+ CASE
WHEN balance.frac < in_history_fee.frac
THEN 100000000
ELSE 0
END;
new_balance.val=balance.val-in_history_fee.val
- CASE
WHEN balance.frac < in_history_fee.frac
THEN 1
ELSE 0
END;
-- Update reserve balance.
UPDATE exchange.reserves
SET current_balance=new_balance
WHERE reserve_pub=in_reserve_pub;
ASSERT FOUND, 'reserve suddenly disappeared';
out_balance_ok=TRUE; out_balance_ok=TRUE;
END $$; END $$;

View File

@ -17,12 +17,10 @@
CREATE OR REPLACE FUNCTION exchange_do_purse_deposit( CREATE OR REPLACE FUNCTION exchange_do_purse_deposit(
IN in_partner_id INT8, IN in_partner_id INT8,
IN in_purse_pub BYTEA, IN in_purse_pub BYTEA,
IN in_amount_with_fee_val INT8, IN in_amount_with_fee taler_amount,
IN in_amount_with_fee_frac INT4,
IN in_coin_pub BYTEA, IN in_coin_pub BYTEA,
IN in_coin_sig BYTEA, IN in_coin_sig BYTEA,
IN in_amount_without_fee_val INT8, IN in_amount_without_fee taler_amount,
IN in_amount_without_fee_frac INT4,
IN in_reserve_expiration INT8, IN in_reserve_expiration INT8,
IN in_now INT8, IN in_now INT8,
OUT out_balance_ok BOOLEAN, OUT out_balance_ok BOOLEAN,
@ -51,8 +49,8 @@ INSERT INTO exchange.purse_deposits
(in_partner_id (in_partner_id
,in_purse_pub ,in_purse_pub
,in_coin_pub ,in_coin_pub
,in_amount_with_fee_val ,in_amount_with_fee.val
,in_amount_with_fee_frac ,in_amount_with_fee.frac
,in_coin_sig) ,in_coin_sig)
ON CONFLICT DO NOTHING; ON CONFLICT DO NOTHING;
@ -100,22 +98,22 @@ END IF;
-- Check and update balance of the coin. -- Check and update balance of the coin.
UPDATE known_coins UPDATE known_coins
SET SET
remaining_frac=remaining_frac-in_amount_with_fee_frac remaining_frac=remaining_frac-in_amount_with_fee.frac
+ CASE + CASE
WHEN remaining_frac < in_amount_with_fee_frac WHEN remaining_frac < in_amount_with_fee.frac
THEN 100000000 THEN 100000000
ELSE 0 ELSE 0
END, END,
remaining_val=remaining_val-in_amount_with_fee_val remaining_val=remaining_val-in_amount_with_fee.val
- CASE - CASE
WHEN remaining_frac < in_amount_with_fee_frac WHEN remaining_frac < in_amount_with_fee.frac
THEN 1 THEN 1
ELSE 0 ELSE 0
END END
WHERE coin_pub=in_coin_pub WHERE coin_pub=in_coin_pub
AND ( (remaining_val > in_amount_with_fee_val) OR AND ( (remaining_val > in_amount_with_fee.val) OR
( (remaining_frac >= in_amount_with_fee_frac) AND ( (remaining_frac >= in_amount_with_fee.frac) AND
(remaining_val >= in_amount_with_fee_val) ) ); (remaining_val >= in_amount_with_fee.val) ) );
IF NOT FOUND IF NOT FOUND
THEN THEN
@ -130,15 +128,15 @@ END IF;
-- Credit the purse. -- Credit the purse.
UPDATE purse_requests UPDATE purse_requests
SET SET
balance_frac=balance_frac+in_amount_without_fee_frac balance_frac=balance_frac+in_amount_without_fee.frac
- CASE - CASE
WHEN balance_frac+in_amount_without_fee_frac >= 100000000 WHEN balance_frac+in_amount_without_fee.frac >= 100000000
THEN 100000000 THEN 100000000
ELSE 0 ELSE 0
END, END,
balance_val=balance_val+in_amount_without_fee_val balance_val=balance_val+in_amount_without_fee.val
+ CASE + CASE
WHEN balance_frac+in_amount_without_fee_frac >= 100000000 WHEN balance_frac+in_amount_without_fee.frac >= 100000000
THEN 1 THEN 1
ELSE 0 ELSE 0
END END
@ -239,15 +237,15 @@ ELSE
-- Reserve existed, thus UPDATE instead of INSERT. -- Reserve existed, thus UPDATE instead of INSERT.
UPDATE reserves UPDATE reserves
SET SET
current_balance.frac=current_balance.frac+my_amount.frac current_balance.frac=(current_balance).frac+my_amount.frac
- CASE - CASE
WHEN current_balance.frac + my_amount.frac >= 100000000 WHEN (current_balance).frac + my_amount.frac >= 100000000
THEN 100000000 THEN 100000000
ELSE 0 ELSE 0
END END
,current_balance.val=current.balance_val+my_amount.val ,current_balance.val=(current_balance).val+my_amount.val
+ CASE + CASE
WHEN current_balance.frac + my_amount.frac >= 100000000 WHEN (current_balance).frac + my_amount.frac >= 100000000
THEN 1 THEN 1
ELSE 0 ELSE 0
END END

View File

@ -33,6 +33,8 @@ DECLARE
my_purse_fee taler_amount; my_purse_fee taler_amount;
my_partner_serial_id INT8; my_partner_serial_id INT8;
my_in_reserve_quota BOOLEAN; my_in_reserve_quota BOOLEAN;
reserve RECORD;
balance taler_amount;
BEGIN BEGIN
@ -195,20 +197,27 @@ ELSE
my_amount.val = my_amount.val + my_amount.frac / 100000000; my_amount.val = my_amount.val + my_amount.frac / 100000000;
my_amount.frac = my_amount.frac % 100000000; my_amount.frac = my_amount.frac % 100000000;
UPDATE exchange.reserves SELECT *
SET INTO reserve
current_balance.frac=current_balance.frac+my_amount.frac FROM exchange.reserves
WHERE reserve_pub=in_reserve_pub;
balance = reserve.current_balance;
balance.frac=balance.frac+my_amount.frac
- CASE - CASE
WHEN current_balance.frac + my_amount.frac >= 100000000 WHEN balance.frac + my_amount.frac >= 100000000
THEN 100000000 THEN 100000000
ELSE 0 ELSE 0
END, END;
current_balance.val=current.balance_val+my.amount_val balance.val=balance.val+my_amount.val
+ CASE + CASE
WHEN current_balance.frac + my_amount.frac >= 100000000 WHEN balance.frac + my_amount.frac >= 100000000
THEN 1 THEN 1
ELSE 0 ELSE 0
END END;
UPDATE exchange.reserves
SET current_balance=balance
WHERE reserve_pub=in_reserve_pub; WHERE reserve_pub=in_reserve_pub;
END IF; END IF;

View File

@ -32,6 +32,9 @@ LANGUAGE plpgsql
AS $$ AS $$
DECLARE DECLARE
tmp taler_amount; -- amount recouped tmp taler_amount; -- amount recouped
balance taler_amount; -- current balance of the reserve
new_balance taler_amount; -- new balance of the reserve
reserve RECORD;
BEGIN BEGIN
-- Shards: SELECT known_coins (by coin_pub) -- Shards: SELECT known_coins (by coin_pub)
-- SELECT recoup (by coin_pub) -- SELECT recoup (by coin_pub)
@ -81,22 +84,31 @@ UPDATE known_coins
,remaining_val=0 ,remaining_val=0
WHERE coin_pub=in_coin_pub; WHERE coin_pub=in_coin_pub;
-- Get current balance
SELECT *
INTO reserve
FROM reserves
WHERE reserve_pub=in_reserve_pub;
balance = reserve.current_balance;
new_balance.frac=balance.frac+tmp.frac
- CASE
WHEN balance.frac+tmp.frac >= 100000000
THEN 100000000
ELSE 0
END;
new_balance.val=balance.val+tmp.val
+ CASE
WHEN balance.frac+tmp.frac >= 100000000
THEN 1
ELSE 0
END;
-- Credit the reserve and update reserve timers. -- Credit the reserve and update reserve timers.
UPDATE reserves UPDATE reserves
SET SET
current_balance.frac=current_balance.frac+tmp.frac current_balance = new_balance,
- CASE
WHEN current_balance.frac+tmp.frac >= 100000000
THEN 100000000
ELSE 0
END,
current_balance.val=current_balance.val+tmp.val
+ CASE
WHEN current_balance.frac+tmp.frac >= 100000000
THEN 1
ELSE 0
END,
gc_date=GREATEST(gc_date, in_reserve_gc), gc_date=GREATEST(gc_date, in_reserve_gc),
expiration_date=GREATEST(expiration_date, in_reserve_expiration) expiration_date=GREATEST(expiration_date, in_reserve_expiration)
WHERE reserve_pub=in_reserve_pub; WHERE reserve_pub=in_reserve_pub;

View File

@ -37,25 +37,15 @@ DECLARE
my_years_tmp INT4; my_years_tmp INT4;
my_years INT4; my_years INT4;
my_needs_update BOOL; my_needs_update BOOL;
my_purses_allowed INT8;
my_expiration_date INT8; my_expiration_date INT8;
my_reserve_expiration INT8; reserve RECORD;
BEGIN BEGIN
-- FIXME: use SELECT FOR UPDATE? -- FIXME: use SELECT FOR UPDATE?
SELECT SELECT *
purses_allowed INTO reserve
,expiration_date
,current_balance.val
,current_balance.frac
INTO
my_purses_allowed
,my_reserve_expiration
,my_balance.val
,my_balance.frac
FROM reserves FROM reserves
WHERE WHERE reserve_pub=in_reserve_pub;
reserve_pub=in_reserve_pub;
IF NOT FOUND IF NOT FOUND
THEN THEN
@ -64,12 +54,14 @@ THEN
RETURN; RETURN;
END IF; END IF;
my_balance = reserve.current_balance;
-- Do not allow expiration time to start in the past already -- Do not allow expiration time to start in the past already
IF (my_reserve_expiration < in_now) IF (reserve.expiration_date < in_now)
THEN THEN
my_expiration_date = in_now; my_expiration_date = in_now;
ELSE ELSE
my_expiration_date = my_reserve_expiration; my_expiration_date = reserve.expiration_date;
END IF; END IF;
my_cost.val = 0; my_cost.val = 0;
@ -81,18 +73,18 @@ my_years = 0;
IF (my_expiration_date < in_desired_expiration) IF (my_expiration_date < in_desired_expiration)
THEN THEN
my_years = (31535999999999 + in_desired_expiration - my_expiration_date) / 31536000000000; my_years = (31535999999999 + in_desired_expiration - my_expiration_date) / 31536000000000;
my_purses_allowed = in_default_purse_limit; reserve.purses_allowed = in_default_purse_limit;
my_expiration_date = my_expiration_date + 31536000000000 * my_years; my_expiration_date = my_expiration_date + 31536000000000 * my_years;
END IF; END IF;
-- Increase years based on purses requested -- Increase years based on purses requested
IF (my_purses_allowed < in_min_purse_limit) IF (reserve.purses_allowed < in_min_purse_limit)
THEN THEN
my_years = (31535999999999 + in_desired_expiration - in_now) / 31536000000000; my_years = (31535999999999 + in_desired_expiration - in_now) / 31536000000000;
my_expiration_date = in_now + 31536000000000 * my_years; my_expiration_date = in_now + 31536000000000 * my_years;
my_years_tmp = (in_min_purse_limit + in_default_purse_limit - my_purses_allowed - 1) / in_default_purse_limit; my_years_tmp = (in_min_purse_limit + in_default_purse_limit - reserve.purses_allowed - 1) / in_default_purse_limit;
my_years = my_years + my_years_tmp; my_years = my_years + my_years_tmp;
my_purses_allowed = my_purses_allowed + (in_default_purse_limit * my_years_tmp); reserve.purses_allowed = reserve.purses_allowed + (in_default_purse_limit * my_years_tmp);
END IF; END IF;
@ -118,7 +110,7 @@ END IF;
-- check if we actually have something to do -- check if we actually have something to do
IF NOT my_needs_update IF NOT my_needs_update
THEN THEN
out_final_expiration = my_reserve_expiration; out_final_expiration = reserve.expiration_date;
out_open_cost.val = 0; out_open_cost.val = 0;
out_open_cost.frac = 0; out_open_cost.frac = 0;
out_no_funds=FALSE; out_no_funds=FALSE;
@ -136,7 +128,7 @@ THEN
out_no_funds=FALSE; out_no_funds=FALSE;
-- We must return a failure, which is indicated by -- We must return a failure, which is indicated by
-- the expiration being below the desired expiration. -- the expiration being below the desired expiration.
IF (my_reserve_expiration >= in_desired_expiration) IF (reserve.expiration_date >= in_desired_expiration)
THEN THEN
-- This case is relevant especially if the purse -- This case is relevant especially if the purse
-- count was to be increased and the payment was -- count was to be increased and the payment was
@ -144,7 +136,7 @@ THEN
RAISE NOTICE 'forcing low expiration time'; RAISE NOTICE 'forcing low expiration time';
out_final_expiration = 0; out_final_expiration = 0;
ELSE ELSE
out_final_expiration = my_reserve_expiration; out_final_expiration = reserve.expiration_date;
END IF; END IF;
RAISE NOTICE 'amount paid too low'; RAISE NOTICE 'amount paid too low';
RETURN; RETURN;
@ -167,7 +159,7 @@ ELSE
my_balance.val=0; my_balance.val=0;
my_balance.frac=my_balance.frac - in_reserve_payment.frac; my_balance.frac=my_balance.frac - in_reserve_payment.frac;
ELSE ELSE
out_final_expiration = my_reserve_expiration; out_final_expiration = reserve.expiration_date;
out_open_cost.val = my_cost.val; out_open_cost.val = my_cost.val;
out_open_cost.frac = my_cost.frac; out_open_cost.frac = my_cost.frac;
out_no_funds=TRUE; out_no_funds=TRUE;
@ -178,9 +170,9 @@ END IF;
UPDATE reserves SET UPDATE reserves SET
current_balance=my_balance current_balance=my_balance
,gc_date=my_reserve_expiration + in_reserve_gc_delay ,gc_date=reserve.expiration_date + in_reserve_gc_delay
,expiration_date=my_expiration_date ,expiration_date=my_expiration_date
,purses_allowed=my_purses_allowed ,purses_allowed=reserve.purses_allowed
WHERE WHERE
reserve_pub=in_reserve_pub; reserve_pub=in_reserve_pub;

View File

@ -117,22 +117,22 @@ ELSE
ELSE ELSE
UPDATE exchange.reserves UPDATE exchange.reserves
SET SET
current_balance.frac=current_balance.frac-in_purse_fee.frac current_balance.frac=(current_balance).frac-in_purse_fee.frac
+ CASE + CASE
WHEN current_balance.frac < in_purse_fee.frac WHEN (current_balance).frac < in_purse_fee.frac
THEN 100000000 THEN 100000000
ELSE 0 ELSE 0
END, END,
current_balance.val=current_balance.val-in_purse_fee.val current_balance.val=(current_balance).val-in_purse_fee.val
- CASE - CASE
WHEN current_balance.frac < in_purse_fee.frac WHEN (current_balance).frac < in_purse_fee.frac
THEN 1 THEN 1
ELSE 0 ELSE 0
END END
WHERE reserve_pub=in_reserve_pub WHERE reserve_pub=in_reserve_pub
AND ( (current_balance.val > in_purse_fee.val) OR AND ( ((current_balance).val > in_purse_fee.val) OR
( (current_balance.frac >= in_purse_fee.frac) AND ( ((current_balance).frac >= in_purse_fee.frac) AND
(current_balance.val >= in_purse_fee.val) ) ); ((current_balance).val >= in_purse_fee.val) ) );
IF NOT FOUND IF NOT FOUND
THEN THEN
out_no_funds=TRUE; out_no_funds=TRUE;

View File

@ -109,11 +109,8 @@ LANGUAGE plpgsql
AS $$ AS $$
DECLARE DECLARE
curs_reserve_exist REFCURSOR; curs_reserve_exist REFCURSOR;
DECLARE
k INT8; k INT8;
DECLARE
curs_transaction_exist REFCURSOR; curs_transaction_exist REFCURSOR;
DECLARE
i RECORD; i RECORD;
BEGIN BEGIN
transaction_duplicate0 = TRUE; transaction_duplicate0 = TRUE;
@ -295,11 +292,8 @@ LANGUAGE plpgsql
AS $$ AS $$
DECLARE DECLARE
curs_reserve_exist REFCURSOR; curs_reserve_exist REFCURSOR;
DECLARE
k INT8; k INT8;
DECLARE
curs_transaction_exist REFCURSOR; curs_transaction_exist REFCURSOR;
DECLARE
i RECORD; i RECORD;
BEGIN BEGIN
transaction_duplicate0=TRUE; transaction_duplicate0=TRUE;
@ -587,13 +581,9 @@ LANGUAGE plpgsql
AS $$ AS $$
DECLARE DECLARE
curs_reserve_exist REFCURSOR; curs_reserve_exist REFCURSOR;
DECLARE
k INT8; k INT8;
DECLARE
curs_transaction_exist REFCURSOR; curs_transaction_exist REFCURSOR;
DECLARE
i RECORD; i RECORD;
DECLARE
r RECORD; r RECORD;
BEGIN BEGIN
@ -949,13 +939,9 @@ LANGUAGE plpgsql
AS $$ AS $$
DECLARE DECLARE
curs REFCURSOR; curs REFCURSOR;
DECLARE
conflict BOOL; conflict BOOL;
DECLARE
dup BOOL; dup BOOL;
DECLARE
uuid INT8; uuid INT8;
DECLARE
i RECORD; i RECORD;
BEGIN BEGIN

View File

@ -35,10 +35,9 @@ CREATE OR REPLACE FUNCTION exchange_do_withdraw(
LANGUAGE plpgsql LANGUAGE plpgsql
AS $$ AS $$
DECLARE DECLARE
reserve_gc INT8; reserve RECORD;
denom_serial INT8; denom_serial INT8;
reserve taler_amount; balance taler_amount;
reserve_birthday INT4;
not_before date; not_before date;
BEGIN BEGIN
-- Shards: reserves by reserve_pub (SELECT) -- Shards: reserves by reserve_pub (SELECT)
@ -65,17 +64,8 @@ THEN
END IF; END IF;
SELECT SELECT *
current_balance INTO reserve
,gc_date
,birthday
,reserve_uuid
INTO
reserve.val
,reserve.frac
,reserve_gc
,reserve_birthday
,ruuid
FROM exchange.reserves FROM exchange.reserves
WHERE reserves.reserve_pub=rpub; WHERE reserves.reserve_pub=rpub;
@ -91,8 +81,11 @@ THEN
RETURN; RETURN;
END IF; END IF;
balance = reserve.current_balance;
ruuid = reserve.reserve_uuid;
-- Check if age requirements are present -- Check if age requirements are present
IF ((NOT do_age_check) OR (reserve_birthday = 0)) IF ((NOT do_age_check) OR (reserve.birthday = 0))
THEN THEN
age_ok = TRUE; age_ok = TRUE;
allowed_maximum_age = -1; allowed_maximum_age = -1;
@ -102,7 +95,7 @@ ELSE
-- birthday set (reserve_birthday != 0), but the client called the -- birthday set (reserve_birthday != 0), but the client called the
-- batch-withdraw endpoint instead of the age-withdraw endpoint, which it -- batch-withdraw endpoint instead of the age-withdraw endpoint, which it
-- should have. -- should have.
not_before=date '1970-01-01' + reserve_birthday; not_before=date '1970-01-01' + reserve.birthday;
allowed_maximum_age = extract(year from age(current_date, not_before)); allowed_maximum_age = extract(year from age(current_date, not_before));
reserve_found=TRUE; reserve_found=TRUE;
@ -144,21 +137,21 @@ THEN
END IF; END IF;
-- Check reserve balance is sufficient. -- Check reserve balance is sufficient.
IF (reserve.val > amount.val) IF (balance.val > amount.val)
THEN THEN
IF (reserve.frac >= amount.frac) IF (balance.frac >= amount.frac)
THEN THEN
reserve.val=reserve.val - amount.val; balance.val=balance.val - amount.val;
reserve.frac=reserve.frac - amount.frac; balance.frac=balance.frac - amount.frac;
ELSE ELSE
reserve.val=reserve.val - amount.val - 1; balance.val=balance.val - amount.val - 1;
reserve.frac=reserve.frac + 100000000 - amount.frac; balance.frac=balance.frac + 100000000 - amount.frac;
END IF; END IF;
ELSE ELSE
IF (reserve.val = amount.val) AND (reserve.frac >= amount.frac) IF (balance.val = amount.val) AND (balance.frac >= amount.frac)
THEN THEN
reserve.val=0; balance.val=0;
reserve.frac=reserve.frac - amount.frac; balance.frac=balance.frac - amount.frac;
ELSE ELSE
reserve_found=TRUE; reserve_found=TRUE;
nonce_ok=TRUE; -- we do not really know nonce_ok=TRUE; -- we do not really know
@ -168,12 +161,12 @@ ELSE
END IF; END IF;
-- Calculate new expiration dates. -- Calculate new expiration dates.
min_reserve_gc=GREATEST(min_reserve_gc,reserve_gc); min_reserve_gc=GREATEST(min_reserve_gc,reserve.gc_date);
-- Update reserve balance. -- Update reserve balance.
UPDATE reserves SET UPDATE reserves SET
gc_date=min_reserve_gc gc_date=min_reserve_gc
,current_balance=reserve ,current_balance=balance
WHERE WHERE
reserves.reserve_pub=rpub; reserves.reserve_pub=rpub;

View File

@ -43,7 +43,8 @@ TEH_PG_do_batch_withdraw (
struct PostgresClosure *pg = cls; struct PostgresClosure *pg = cls;
struct GNUNET_TIME_Timestamp gc; struct GNUNET_TIME_Timestamp gc;
struct GNUNET_PQ_QueryParam params[] = { struct GNUNET_PQ_QueryParam params[] = {
TALER_PQ_query_param_amount (amount), TALER_PQ_query_param_amount_tuple (pg->conn,
amount),
GNUNET_PQ_query_param_auto_from_type (reserve_pub), GNUNET_PQ_query_param_auto_from_type (reserve_pub),
GNUNET_PQ_query_param_timestamp (&now), GNUNET_PQ_query_param_timestamp (&now),
GNUNET_PQ_query_param_timestamp (&gc), GNUNET_PQ_query_param_timestamp (&gc),
@ -80,7 +81,7 @@ TEH_PG_do_batch_withdraw (
",allowed_maximum_age" ",allowed_maximum_age"
",ruuid" ",ruuid"
" FROM exchange_do_batch_withdraw" " FROM exchange_do_batch_withdraw"
" ($1,$2,$3,$4,$5,$6);"); " ($1,$2,$3,$4,$5);");
return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"call_batch_withdraw", "call_batch_withdraw",
params, params,

View File

@ -47,10 +47,14 @@ TEH_PG_do_purse_deposit (
? GNUNET_PQ_query_param_null () ? GNUNET_PQ_query_param_null ()
: GNUNET_PQ_query_param_uint64 (&partner_id), : GNUNET_PQ_query_param_uint64 (&partner_id),
GNUNET_PQ_query_param_auto_from_type (purse_pub), GNUNET_PQ_query_param_auto_from_type (purse_pub),
TALER_PQ_query_param_amount (amount), TALER_PQ_query_param_amount_tuple (
pg->conn,
amount),
GNUNET_PQ_query_param_auto_from_type (coin_pub), GNUNET_PQ_query_param_auto_from_type (coin_pub),
GNUNET_PQ_query_param_auto_from_type (coin_sig), GNUNET_PQ_query_param_auto_from_type (coin_sig),
TALER_PQ_query_param_amount (amount_minus_fee), TALER_PQ_query_param_amount_tuple (
pg->conn,
amount_minus_fee),
GNUNET_PQ_query_param_timestamp (&reserve_expiration), GNUNET_PQ_query_param_timestamp (&reserve_expiration),
GNUNET_PQ_query_param_timestamp (&now), GNUNET_PQ_query_param_timestamp (&now),
GNUNET_PQ_query_param_end GNUNET_PQ_query_param_end
@ -77,7 +81,7 @@ TEH_PG_do_purse_deposit (
",out_conflict AS conflict" ",out_conflict AS conflict"
",out_late AS too_late" ",out_late AS too_late"
" FROM exchange_do_purse_deposit" " FROM exchange_do_purse_deposit"
" ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10);"); " ($1,$2,$3,$4,$5,$6,$7,$8);");
return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"call_purse_deposit", "call_purse_deposit",

View File

@ -44,19 +44,25 @@ TEH_PG_do_reserve_open (
struct PostgresClosure *pg = cls; struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = { struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_auto_from_type (reserve_pub), GNUNET_PQ_query_param_auto_from_type (reserve_pub),
TALER_PQ_query_param_amount (total_paid), TALER_PQ_query_param_amount_tuple (
TALER_PQ_query_param_amount (reserve_payment), pg->conn,
total_paid),
TALER_PQ_query_param_amount_tuple (
pg->conn,
reserve_payment),
GNUNET_PQ_query_param_uint32 (&min_purse_limit), GNUNET_PQ_query_param_uint32 (&min_purse_limit),
GNUNET_PQ_query_param_uint32 (&pg->def_purse_limit), GNUNET_PQ_query_param_uint32 (&pg->def_purse_limit),
GNUNET_PQ_query_param_auto_from_type (reserve_sig), GNUNET_PQ_query_param_auto_from_type (reserve_sig),
GNUNET_PQ_query_param_timestamp (&desired_expiration), GNUNET_PQ_query_param_timestamp (&desired_expiration),
GNUNET_PQ_query_param_relative_time (&pg->legal_reserve_expiration_time), GNUNET_PQ_query_param_relative_time (&pg->legal_reserve_expiration_time),
GNUNET_PQ_query_param_timestamp (&now), GNUNET_PQ_query_param_timestamp (&now),
TALER_PQ_query_param_amount (open_fee), TALER_PQ_query_param_amount_tuple (pg->conn,
open_fee),
GNUNET_PQ_query_param_end GNUNET_PQ_query_param_end
}; };
struct GNUNET_PQ_ResultSpec rs[] = { struct GNUNET_PQ_ResultSpec rs[] = {
TALER_PQ_RESULT_SPEC_AMOUNT ("out_open_cost", TALER_PQ_result_spec_amount_tuple ("out_open_cost",
pg->currency,
open_cost), open_cost),
GNUNET_PQ_result_spec_timestamp ("out_final_expiration", GNUNET_PQ_result_spec_timestamp ("out_final_expiration",
final_expiration), final_expiration),
@ -68,12 +74,11 @@ TEH_PG_do_reserve_open (
PREPARE (pg, PREPARE (pg,
"do_reserve_open", "do_reserve_open",
"SELECT " "SELECT "
" out_open_cost_val" " out_open_cost"
",out_open_cost_frac"
",out_final_expiration" ",out_final_expiration"
",out_no_funds" ",out_no_funds"
" FROM exchange_do_reserve_open" " FROM exchange_do_reserve_open"
" ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13);"); " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10);");
return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"do_reserve_open", "do_reserve_open",
params, params,

View File

@ -74,7 +74,8 @@ TEH_PG_do_reserve_purse (
GNUNET_PQ_query_param_timestamp (&reserve_gc), GNUNET_PQ_query_param_timestamp (&reserve_gc),
GNUNET_PQ_query_param_auto_from_type (reserve_sig), GNUNET_PQ_query_param_auto_from_type (reserve_sig),
GNUNET_PQ_query_param_bool (NULL == purse_fee), GNUNET_PQ_query_param_bool (NULL == purse_fee),
TALER_PQ_query_param_amount (NULL == purse_fee TALER_PQ_query_param_amount_tuple (pg->conn,
NULL == purse_fee
? &zero_fee ? &zero_fee
: purse_fee), : purse_fee),
GNUNET_PQ_query_param_auto_from_type (reserve_pub), GNUNET_PQ_query_param_auto_from_type (reserve_pub),
@ -111,7 +112,7 @@ TEH_PG_do_reserve_purse (
",out_no_reserve AS no_reserve" ",out_no_reserve AS no_reserve"
",out_conflict AS conflict" ",out_conflict AS conflict"
" FROM exchange_do_reserve_purse" " FROM exchange_do_reserve_purse"
" ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11);"); " ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);");
return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"call_reserve_purse", "call_reserve_purse",

View File

@ -138,7 +138,7 @@ TEH_PG_get_expired_reserves (void *cls,
" SELECT * " " SELECT * "
" FROM reserves " " FROM reserves "
" WHERE expiration_date <= $1 " " WHERE expiration_date <= $1 "
" AND (current_balance.val != 0 OR current_balance.frac != 0) " " AND ((current_balance).val != 0 OR (current_balance).frac != 0) "
" ORDER BY expiration_date ASC " " ORDER BY expiration_date ASC "
" LIMIT 1 " " LIMIT 1 "
") " ") "

View File

@ -41,7 +41,8 @@ TEH_PG_insert_history_request (
GNUNET_PQ_query_param_auto_from_type (reserve_pub), GNUNET_PQ_query_param_auto_from_type (reserve_pub),
GNUNET_PQ_query_param_auto_from_type (reserve_sig), GNUNET_PQ_query_param_auto_from_type (reserve_sig),
GNUNET_PQ_query_param_timestamp (&request_timestamp), GNUNET_PQ_query_param_timestamp (&request_timestamp),
TALER_PQ_query_param_amount (history_fee), TALER_PQ_query_param_amount_tuple (pg->conn,
history_fee),
GNUNET_PQ_query_param_end GNUNET_PQ_query_param_end
}; };
struct GNUNET_PQ_ResultSpec rs[] = { struct GNUNET_PQ_ResultSpec rs[] = {
@ -58,7 +59,7 @@ TEH_PG_insert_history_request (
" out_balance_ok AS balance_ok" " out_balance_ok AS balance_ok"
" ,out_idempotent AS idempotent" " ,out_idempotent AS idempotent"
" FROM exchange_do_history_request" " FROM exchange_do_history_request"
" ($1, $2, $3, $4, $5)"); " ($1, $2, $3, $4)");
return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"call_history_request", "call_history_request",
params, params,