Compare commits

...

4 Commits

Author SHA1 Message Date
a1dae0199f
FAILING attempt to make echange.reserve use taler_amount
Fails with

> TALER_PREFIX=/usr/local ./test-exchangedb-postgres
2023-07-28T19:02:25.150845+0200 /home/oec/projects/taler/exchange/src/exchangedb/.libs/test-exchangedb-postgres-2559159 WARNING Could not run PSQL on file /usr/local/share/taler//sql/exchange/drop.sql: psql exit code was 3
2023-07-28T19:02:32.488085+0200 pq-2559159 ERROR Query `call_withdraw' failed with result: invalid input syntax for type bigint:
"(1,1000)"/(null)/ERROR:  invalid input syntax for type bigint: "(1,1000)"
CONTEXT:  PL/pgSQL function exchange_do_withdraw(bytea,taler_amount,bytea,bytea,bytea,bytea,bytea,bigint,bigint,boolean) line 23 at SQL statement
/PGRES_FATAL_ERROR/ERROR:  invalid input syntax for type bigint: "(1,1000)"
CONTEXT:  PL/pgSQL function exchange_do_withdraw(bytea,taler_amount,bytea,bytea,bytea,bytea,bytea,bigint,bigint,boolean) line 23 at SQL statement
2023-07-28T19:02:32.488146+0200 /home/oec/projects/taler/exchange/src/exchangedb/.libs/test-exchangedb-postgres-2559159 ERROR Assertion failed at test_exchangedb.c:1428.
2023-07-28 19:01:57 +02:00
8f9731e830
Merge branch 'new-amount', lookup OIDs for composites 2023-07-28 16:22:48 +02:00
Christian Grothoff
429aeb9e5e
-ignore 2023-07-28 16:21:08 +02:00
94e5193bff
[pq] added helper to load oids of composite types
- TALER_PQ_load_oids_for_composite_types added
- Called during postgres-initialization
2023-07-28 16:19:21 +02:00
31 changed files with 350 additions and 344 deletions

View File

@ -24,3 +24,5 @@ taler-auditor-test.sqlite3
libeufin-nexus.pid libeufin-nexus.pid
libeufin-sandbox.pid libeufin-sandbox.pid
taler-helper-auditor-purses taler-helper-auditor-purses
generate-kyc-basedb.conf.edited
generate-auditor-basedb.conf.edited

View File

@ -27,8 +27,7 @@ BEGIN
'CREATE TABLE %I' 'CREATE TABLE %I'
'(reserve_uuid BIGINT GENERATED BY DEFAULT AS IDENTITY' '(reserve_uuid BIGINT GENERATED BY DEFAULT AS IDENTITY'
',reserve_pub BYTEA PRIMARY KEY CHECK(LENGTH(reserve_pub)=32)' ',reserve_pub BYTEA PRIMARY KEY CHECK(LENGTH(reserve_pub)=32)'
',current_balance_val INT8 NOT NULL DEFAULT(0)' ',current_balance taler_amount NOT NULL DEFAULT (0, 0)'
',current_balance_frac INT4 NOT NULL DEFAULT(0)'
',purses_active INT8 NOT NULL DEFAULT(0)' ',purses_active INT8 NOT NULL DEFAULT(0)'
',purses_allowed INT8 NOT NULL DEFAULT(0)' ',purses_allowed INT8 NOT NULL DEFAULT(0)'
',birthday INT4 NOT NULL DEFAULT(0)' ',birthday INT4 NOT NULL DEFAULT(0)'
@ -52,7 +51,7 @@ BEGIN
); );
PERFORM comment_partitioned_column( PERFORM comment_partitioned_column(
'Current balance remaining with the reserve.' 'Current balance remaining with the reserve.'
,'current_balance_val' ,'current_balance'
,table_name ,table_name
,partition_suffix ,partition_suffix
); );
@ -109,8 +108,7 @@ BEGIN
'CREATE INDEX ' || table_name || '_by_expiration_index ' 'CREATE INDEX ' || table_name || '_by_expiration_index '
'ON ' || table_name || ' ' 'ON ' || table_name || ' '
'(expiration_date' '(expiration_date'
',current_balance_val' ',current_balance'
',current_balance_frac'
');' ');'
); );
EXECUTE FORMAT ( EXECUTE FORMAT (

View File

@ -50,8 +50,7 @@ BEGIN
-- wire_targets by wire_target_h_payto -- wire_targets by wire_target_h_payto
SELECT SELECT
current_balance_val current_balance
,current_balance_frac
,gc_date ,gc_date
,birthday ,birthday
INTO INTO
@ -126,8 +125,7 @@ min_reserve_gc=GREATEST(min_reserve_gc,reserve_gc);
-- Update reserve balance. -- Update reserve balance.
UPDATE reserves SET UPDATE reserves SET
gc_date=min_reserve_gc gc_date=min_reserve_gc
,current_balance_val=new_balance.val ,current_balance=new_balance
,current_balance_frac=new_balance.frac
WHERE WHERE
reserves.reserve_pub=rpub; reserves.reserve_pub=rpub;

View File

@ -18,8 +18,7 @@ CREATE OR REPLACE FUNCTION exchange_do_batch_reserves_update(
IN in_reserve_pub BYTEA, IN in_reserve_pub BYTEA,
IN in_expiration_date INT8, IN in_expiration_date INT8,
IN in_wire_ref INT8, IN in_wire_ref INT8,
IN in_credit_val INT8, IN in_credit taler_amount,
IN in_credit_frac INT4,
IN in_exchange_account_name VARCHAR, IN in_exchange_account_name VARCHAR,
IN in_wire_source_h_payto BYTEA, IN in_wire_source_h_payto BYTEA,
IN in_notify text, IN in_notify text,
@ -38,8 +37,8 @@ BEGIN
VALUES VALUES
(in_reserve_pub (in_reserve_pub
,in_wire_ref ,in_wire_ref
,in_credit_val ,in_credit.val
,in_credit_frac ,in_credit.frac
,in_exchange_account_name ,in_exchange_account_name
,in_wire_source_h_payto ,in_wire_source_h_payto
,in_expiration_date) ,in_expiration_date)
@ -50,15 +49,15 @@ BEGIN
out_duplicate = FALSE; out_duplicate = FALSE;
UPDATE reserves UPDATE reserves
SET SET
current_balance_frac = current_balance_frac+in_credit_frac current_balance.frac = current_balance.frac+in_credit.frac
- CASE - CASE
WHEN current_balance_frac + in_credit_frac >= 100000000 WHEN current_balance.frac + in_credit.frac >= 100000000
THEN 100000000 THEN 100000000
ELSE 1 ELSE 1
END END
,current_balance_val = current_balance_val+in_credit_val ,current_balance.val = current_balance.val+in_credit.val
+ CASE + CASE
WHEN current_balance_frac + in_credit_frac >= 100000000 WHEN current_balance.frac + in_credit.frac >= 100000000
THEN 1 THEN 1
ELSE 0 ELSE 0
END END

View File

@ -17,8 +17,7 @@
-- @author Özgür Kesim -- @author Özgür Kesim
CREATE OR REPLACE FUNCTION exchange_do_batch_withdraw( CREATE OR REPLACE FUNCTION exchange_do_batch_withdraw(
IN amount_val INT8, IN amount taler_amount,
IN amount_frac INT4,
IN rpub BYTEA, IN rpub BYTEA,
IN now INT8, IN now INT8,
IN min_reserve_gc INT8, IN min_reserve_gc INT8,
@ -32,8 +31,7 @@ LANGUAGE plpgsql
AS $$ AS $$
DECLARE DECLARE
reserve_gc INT8; reserve_gc INT8;
reserve_val INT8; reserve taler_amount;
reserve_frac INT4;
reserve_birthday INT4; reserve_birthday INT4;
not_before date; not_before date;
BEGIN BEGIN
@ -45,14 +43,14 @@ BEGIN
SELECT SELECT
current_balance_val current_balance.val
,current_balance_frac ,current_balance.frac
,gc_date ,gc_date
,birthday ,birthday
,reserve_uuid ,reserve_uuid
INTO INTO
reserve_val reserve.val
,reserve_frac ,reserve.frac
,reserve_gc ,reserve_gc
,reserve_birthday ,reserve_birthday
,ruuid ,ruuid
@ -92,21 +90,21 @@ ELSE
END IF; END IF;
-- Check reserve balance is sufficient. -- Check reserve balance is sufficient.
IF (reserve_val > amount_val) IF (reserve.val > amount.val)
THEN THEN
IF (reserve_frac >= amount_frac) IF (reserve.frac >= amount.frac)
THEN THEN
reserve_val=reserve_val - amount_val; reserve.val=reserve.val - amount.val;
reserve_frac=reserve_frac - amount_frac; reserve.frac=reserve.frac - amount.frac;
ELSE ELSE
reserve_val=reserve_val - amount_val - 1; reserve.val=reserve.val - amount.val - 1;
reserve_frac=reserve_frac + 100000000 - amount_frac; reserve.frac=reserve.frac + 100000000 - amount.frac;
END IF; END IF;
ELSE ELSE
IF (reserve_val = amount_val) AND (reserve_frac >= amount_frac) IF (reserve.val = amount.val) AND (reserve.frac >= amount.frac)
THEN THEN
reserve_val=0; reserve.val=0;
reserve_frac=reserve_frac - amount_frac; reserve.frac=reserve.frac - amount.frac;
ELSE ELSE
balance_ok=FALSE; balance_ok=FALSE;
RETURN; RETURN;
@ -119,8 +117,7 @@ min_reserve_gc=GREATEST(min_reserve_gc,reserve_gc);
-- Update reserve balance. -- Update reserve balance.
UPDATE reserves SET UPDATE reserves SET
gc_date=min_reserve_gc gc_date=min_reserve_gc
,current_balance_val=reserve_val ,current_balance=reserve
,current_balance_frac=reserve_frac
WHERE WHERE
reserves.reserve_pub=rpub; reserves.reserve_pub=rpub;
@ -129,6 +126,6 @@ balance_ok=TRUE;
END $$; END $$;
COMMENT ON FUNCTION exchange_do_batch_withdraw(INT8, INT4, BYTEA, INT8, INT8, BOOLEAN) COMMENT ON FUNCTION exchange_do_batch_withdraw(taler_amount, BYTEA, INT8, INT8, BOOLEAN)
IS 'Checks whether the reserve has sufficient balance for a withdraw operation (or the request is repeated and was previously approved) and that age requirements are formally met. If so updates the database with the result. Excludes storing the planchets.'; IS 'Checks whether the reserve has sufficient balance for a withdraw operation (or the request is repeated and was previously approved) and that age requirements are formally met. If so updates the database with the result. Excludes storing the planchets.';

View File

@ -21,15 +21,10 @@ LANGUAGE plpgsql
AS $$ AS $$
DECLARE DECLARE
reserve_uuid_min INT8; -- minimum reserve UUID still alive reserve_uuid_min INT8; -- minimum reserve UUID still alive
DECLARE
melt_min INT8; -- minimum melt still alive melt_min INT8; -- minimum melt still alive
DECLARE
coin_min INT8; -- minimum known_coin still alive coin_min INT8; -- minimum known_coin still alive
DECLARE
deposit_min INT8; -- minimum deposit still alive deposit_min INT8; -- minimum deposit still alive
DECLARE
reserve_out_min INT8; -- minimum reserve_out still alive reserve_out_min INT8; -- minimum reserve_out still alive
DECLARE
denom_min INT8; -- minimum denomination still alive denom_min INT8; -- minimum denomination still alive
BEGIN BEGIN
@ -42,8 +37,8 @@ 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.val = 0
AND current_balance_frac = 0; AND current_balance.frac = 0;
SELECT SELECT
reserve_out_serial_id reserve_out_serial_id

View File

@ -54,23 +54,23 @@ BEGIN
-- Update reserve balance. -- Update reserve balance.
UPDATE exchange.reserves UPDATE exchange.reserves
SET SET
current_balance_frac=current_balance_frac-in_history_fee_frac current_balance.frac=current_balance.frac-in_history_fee_frac
+ CASE + CASE
WHEN current_balance_frac < in_history_fee_frac WHEN current_balance.frac < in_history_fee_frac
THEN 100000000 THEN 100000000
ELSE 0 ELSE 0
END, END,
current_balance_val=current_balance_val-in_history_fee_val current_balance.val=current_balance.val-in_history_fee_val
- CASE - CASE
WHEN current_balance_frac < in_history_fee_frac WHEN current_balance.frac < in_history_fee_frac
THEN 1 THEN 1
ELSE 0 ELSE 0
END END
WHERE WHERE
reserve_pub=in_reserve_pub reserve_pub=in_reserve_pub
AND ( (current_balance_val > in_history_fee_val) OR AND ( (current_balance.val > in_history_fee_val) OR
( (current_balance_frac >= in_history_fee_frac) AND ( (current_balance.frac >= in_history_fee_frac) AND
(current_balance_val >= in_history_fee_val) ) ); (current_balance.val >= in_history_fee_val) ) );
IF NOT FOUND IF NOT FOUND
THEN THEN

View File

@ -32,17 +32,10 @@ LANGUAGE plpgsql
AS $$ AS $$
DECLARE DECLARE
was_merged BOOLEAN; was_merged BOOLEAN;
DECLARE
psi INT8; -- partner's serial ID (set if merged) psi INT8; -- partner's serial ID (set if merged)
DECLARE my_amount taler_amount; -- total in purse
my_amount_val INT8; -- total in purse
DECLARE
my_amount_frac INT4; -- total in purse
DECLARE
was_paid BOOLEAN; was_paid BOOLEAN;
DECLARE
my_in_reserve_quota BOOLEAN; my_in_reserve_quota BOOLEAN;
DECLARE
my_reserve_pub BYTEA; my_reserve_pub BYTEA;
BEGIN BEGIN
@ -174,8 +167,8 @@ SELECT
,amount_with_fee_frac ,amount_with_fee_frac
,in_reserve_quota ,in_reserve_quota
INTO INTO
my_amount_val my_amount.val
,my_amount_frac ,my_amount.frac
,my_in_reserve_quota ,my_in_reserve_quota
FROM exchange.purse_requests FROM exchange.purse_requests
WHERE (purse_pub=in_purse_pub) WHERE (purse_pub=in_purse_pub)
@ -231,14 +224,12 @@ ELSE
-- This is a local reserve, update balance immediately. -- This is a local reserve, update balance immediately.
INSERT INTO reserves INSERT INTO reserves
(reserve_pub (reserve_pub
,current_balance_frac ,current_balance
,current_balance_val
,expiration_date ,expiration_date
,gc_date) ,gc_date)
VALUES VALUES
(my_reserve_pub (my_reserve_pub
,my_amount_frac ,my_amount
,my_amount_val
,in_reserve_expiration ,in_reserve_expiration
,in_reserve_expiration) ,in_reserve_expiration)
ON CONFLICT DO NOTHING; ON CONFLICT DO NOTHING;
@ -248,15 +239,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

@ -29,16 +29,9 @@ CREATE OR REPLACE FUNCTION exchange_do_purse_merge(
LANGUAGE plpgsql LANGUAGE plpgsql
AS $$ AS $$
DECLARE DECLARE
my_amount_val INT8; my_amount taler_amount;
DECLARE my_purse_fee taler_amount;
my_amount_frac INT4;
DECLARE
my_purse_fee_val INT8;
DECLARE
my_purse_fee_frac INT4;
DECLARE
my_partner_serial_id INT8; my_partner_serial_id INT8;
DECLARE
my_in_reserve_quota BOOLEAN; my_in_reserve_quota BOOLEAN;
BEGIN BEGIN
@ -72,10 +65,10 @@ SELECT amount_with_fee_val
,purse_fee_val ,purse_fee_val
,purse_fee_frac ,purse_fee_frac
,in_reserve_quota ,in_reserve_quota
INTO my_amount_val INTO my_amount.val
,my_amount_frac ,my_amount.frac
,my_purse_fee_val ,my_purse_fee.val
,my_purse_fee_frac ,my_purse_fee.frac
,my_in_reserve_quota ,my_in_reserve_quota
FROM exchange.purse_requests FROM exchange.purse_requests
WHERE purse_pub=in_purse_pub WHERE purse_pub=in_purse_pub
@ -196,23 +189,23 @@ ELSE
-- This is a local reserve, update reserve balance immediately. -- This is a local reserve, update reserve balance immediately.
-- Refund the purse fee, by adding it to the purse value: -- Refund the purse fee, by adding it to the purse value:
my_amount_val = my_amount_val + my_purse_fee_val; my_amount.val = my_amount.val + my_purse_fee.val;
my_amount_frac = my_amount_frac + my_purse_fee_frac; my_amount.frac = my_amount.frac + my_purse_fee.frac;
-- normalize result -- normalize result
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 UPDATE exchange.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

@ -31,9 +31,7 @@ CREATE OR REPLACE FUNCTION exchange_do_recoup_to_reserve(
LANGUAGE plpgsql LANGUAGE plpgsql
AS $$ AS $$
DECLARE DECLARE
tmp_val INT8; -- amount recouped tmp taler_amount; -- amount recouped
DECLARE
tmp_frac INT8; -- amount recouped
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)
@ -49,8 +47,8 @@ SELECT
remaining_frac remaining_frac
,remaining_val ,remaining_val
INTO INTO
tmp_frac tmp.frac
,tmp_val ,tmp.val
FROM exchange.known_coins FROM exchange.known_coins
WHERE coin_pub=in_coin_pub; WHERE coin_pub=in_coin_pub;
@ -61,7 +59,7 @@ THEN
RETURN; RETURN;
END IF; END IF;
IF tmp_val + tmp_frac = 0 IF tmp.val + tmp.frac = 0
THEN THEN
-- Check for idempotency -- Check for idempotency
SELECT SELECT
@ -87,15 +85,15 @@ UPDATE known_coins
-- 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.frac=current_balance.frac+tmp.frac
- CASE - CASE
WHEN current_balance_frac+tmp_frac >= 100000000 WHEN current_balance.frac+tmp.frac >= 100000000
THEN 100000000 THEN 100000000
ELSE 0 ELSE 0
END, END,
current_balance_val=current_balance_val+tmp_val current_balance.val=current_balance.val+tmp.val
+ CASE + CASE
WHEN current_balance_frac+tmp_frac >= 100000000 WHEN current_balance.frac+tmp.frac >= 100000000
THEN 1 THEN 1
ELSE 0 ELSE 0
END, END,
@ -126,8 +124,8 @@ VALUES
(in_coin_pub (in_coin_pub
,in_coin_sig ,in_coin_sig
,in_coin_blind ,in_coin_blind
,tmp_val ,tmp.val
,tmp_frac ,tmp.frac
,in_recoup_timestamp ,in_recoup_timestamp
,in_reserve_out_serial_id); ,in_reserve_out_serial_id);

View File

@ -16,45 +16,29 @@
CREATE OR REPLACE FUNCTION exchange_do_reserve_open( CREATE OR REPLACE FUNCTION exchange_do_reserve_open(
IN in_reserve_pub BYTEA, IN in_reserve_pub BYTEA,
IN in_total_paid_val INT8, IN in_total_paid taler_amount,
IN in_total_paid_frac INT4, IN in_reserve_payment taler_amount,
IN in_reserve_payment_val INT8,
IN in_reserve_payment_frac INT4,
IN in_min_purse_limit INT4, IN in_min_purse_limit INT4,
IN in_default_purse_limit INT4, IN in_default_purse_limit INT4,
IN in_reserve_sig BYTEA, IN in_reserve_sig BYTEA,
IN in_desired_expiration INT8, IN in_desired_expiration INT8,
IN in_reserve_gc_delay INT8, IN in_reserve_gc_delay INT8,
IN in_now INT8, IN in_now INT8,
IN in_open_fee_val INT8, IN in_open_fee taler_amount,
IN in_open_fee_frac INT4, OUT out_open_cost taler_amount,
OUT out_open_cost_val INT8,
OUT out_open_cost_frac INT4,
OUT out_final_expiration INT8, OUT out_final_expiration INT8,
OUT out_no_funds BOOLEAN) OUT out_no_funds BOOLEAN)
LANGUAGE plpgsql LANGUAGE plpgsql
AS $$ AS $$
DECLARE DECLARE
my_balance_val INT8; my_balance taler_amount;
DECLARE my_cost taler_amount;
my_balance_frac INT4;
DECLARE
my_cost_val INT8;
DECLARE
my_cost_tmp INT8; my_cost_tmp INT8;
DECLARE
my_cost_frac INT4;
DECLARE
my_years_tmp INT4; my_years_tmp INT4;
DECLARE
my_years INT4; my_years INT4;
DECLARE
my_needs_update BOOL; my_needs_update BOOL;
DECLARE
my_purses_allowed INT8; my_purses_allowed INT8;
DECLARE
my_expiration_date INT8; my_expiration_date INT8;
DECLARE
my_reserve_expiration INT8; my_reserve_expiration INT8;
BEGIN BEGIN
@ -62,13 +46,13 @@ BEGIN
SELECT SELECT
purses_allowed purses_allowed
,expiration_date ,expiration_date
,current_balance_val ,current_balance.val
,current_balance_frac ,current_balance.frac
INTO INTO
my_purses_allowed my_purses_allowed
,my_reserve_expiration ,my_reserve_expiration
,my_balance_val ,my_balance.val
,my_balance_frac ,my_balance.frac
FROM reserves FROM reserves
WHERE WHERE
reserve_pub=in_reserve_pub; reserve_pub=in_reserve_pub;
@ -88,8 +72,8 @@ ELSE
my_expiration_date = my_reserve_expiration; my_expiration_date = my_reserve_expiration;
END IF; END IF;
my_cost_val = 0; my_cost.val = 0;
my_cost_frac = 0; my_cost.frac = 0;
my_needs_update = FALSE; my_needs_update = FALSE;
my_years = 0; my_years = 0;
@ -115,19 +99,19 @@ END IF;
-- Compute cost based on annual fees -- Compute cost based on annual fees
IF (my_years > 0) IF (my_years > 0)
THEN THEN
my_cost_val = my_years * in_open_fee_val; my_cost.val = my_years * in_open_fee.val;
my_cost_tmp = my_years * in_open_fee_frac / 100000000; my_cost_tmp = my_years * in_open_fee.frac / 100000000;
IF (CAST (my_cost_val + my_cost_tmp AS INT8) < my_cost_val) IF (CAST (my_cost.val + my_cost_tmp AS INT8) < my_cost.val)
THEN THEN
out_open_cost_val=9223372036854775807; out_open_cost.val=9223372036854775807;
out_open_cost_frac=2147483647; out_open_cost.frac=2147483647;
out_final_expiration=my_expiration_date; out_final_expiration=my_expiration_date;
out_no_funds=FALSE; out_no_funds=FALSE;
RAISE NOTICE 'arithmetic issue computing amount'; RAISE NOTICE 'arithmetic issue computing amount';
RETURN; RETURN;
END IF; END IF;
my_cost_val = CAST (my_cost_val + my_cost_tmp AS INT8); my_cost.val = CAST (my_cost.val + my_cost_tmp AS INT8);
my_cost_frac = my_years * in_open_fee_frac % 100000000; my_cost.frac = my_years * in_open_fee.frac % 100000000;
my_needs_update = TRUE; my_needs_update = TRUE;
END IF; END IF;
@ -135,20 +119,20 @@ END IF;
IF NOT my_needs_update IF NOT my_needs_update
THEN THEN
out_final_expiration = my_reserve_expiration; out_final_expiration = my_reserve_expiration;
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;
RAISE NOTICE 'no change required'; RAISE NOTICE 'no change required';
RETURN; RETURN;
END IF; END IF;
-- Check payment (coins and reserve) would be sufficient. -- Check payment (coins and reserve) would be sufficient.
IF ( (in_total_paid_val < my_cost_val) OR IF ( (in_total_paid.val < my_cost.val) OR
( (in_total_paid_val = my_cost_val) AND ( (in_total_paid.val = my_cost.val) AND
(in_total_paid_frac < my_cost_frac) ) ) (in_total_paid.frac < my_cost.frac) ) )
THEN THEN
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=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.
@ -167,25 +151,25 @@ THEN
END IF; END IF;
-- Check reserve balance is sufficient. -- Check reserve balance is sufficient.
IF (my_balance_val > in_reserve_payment_val) IF (my_balance.val > in_reserve_payment.val)
THEN THEN
IF (my_balance_frac >= in_reserve_payment_frac) IF (my_balance.frac >= in_reserve_payment.frac)
THEN THEN
my_balance_val=my_balance_val - in_reserve_payment_val; my_balance.val=my_balance.val - in_reserve_payment.val;
my_balance_frac=my_balance_frac - in_reserve_payment_frac; my_balance.frac=my_balance.frac - in_reserve_payment.frac;
ELSE ELSE
my_balance_val=my_balance_val - in_reserve_payment_val - 1; my_balance.val=my_balance.val - in_reserve_payment.val - 1;
my_balance_frac=my_balance_frac + 100000000 - in_reserve_payment_frac; my_balance.frac=my_balance.frac + 100000000 - in_reserve_payment.frac;
END IF; END IF;
ELSE ELSE
IF (my_balance_val = in_reserve_payment_val) AND (my_balance_frac >= in_reserve_payment_frac) IF (my_balance.val = in_reserve_payment.val) AND (my_balance.frac >= in_reserve_payment.frac)
THEN THEN
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 = my_reserve_expiration;
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;
RAISE NOTICE 'reserve balance too low'; RAISE NOTICE 'reserve balance too low';
RETURN; RETURN;
@ -193,8 +177,7 @@ ELSE
END IF; END IF;
UPDATE reserves SET UPDATE reserves SET
current_balance_val=my_balance_val current_balance=my_balance
,current_balance_frac=my_balance_frac
,gc_date=my_reserve_expiration + in_reserve_gc_delay ,gc_date=my_reserve_expiration + in_reserve_gc_delay
,expiration_date=my_expiration_date ,expiration_date=my_expiration_date
,purses_allowed=my_purses_allowed ,purses_allowed=my_purses_allowed
@ -202,8 +185,7 @@ WHERE
reserve_pub=in_reserve_pub; reserve_pub=in_reserve_pub;
out_final_expiration=my_expiration_date; out_final_expiration=my_expiration_date;
out_open_cost_val = my_cost_val; out_open_cost = my_cost;
out_open_cost_frac = my_cost_frac;
out_no_funds=FALSE; out_no_funds=FALSE;
RETURN; RETURN;

View File

@ -22,8 +22,7 @@ CREATE OR REPLACE FUNCTION exchange_do_reserve_purse(
IN in_reserve_gc INT8, IN in_reserve_gc INT8,
IN in_reserve_sig BYTEA, IN in_reserve_sig BYTEA,
IN in_reserve_quota BOOLEAN, IN in_reserve_quota BOOLEAN,
IN in_purse_fee_val INT8, IN in_purse_fee taler_amount,
IN in_purse_fee_frac INT4,
IN in_reserve_pub BYTEA, IN in_reserve_pub BYTEA,
IN in_wallet_h_payto BYTEA, IN in_wallet_h_payto BYTEA,
OUT out_no_funds BOOLEAN, OUT out_no_funds BOOLEAN,
@ -101,8 +100,8 @@ ELSE
-- UPDATE reserves balance (and check if balance is enough to pay the fee) -- UPDATE reserves balance (and check if balance is enough to pay the fee)
IF (out_no_reserve) IF (out_no_reserve)
THEN THEN
IF ( (0 != in_purse_fee_val) OR IF ( (0 != in_purse_fee.val) OR
(0 != in_purse_fee_frac) ) (0 != in_purse_fee.frac) )
THEN THEN
out_no_funds=TRUE; out_no_funds=TRUE;
RETURN; RETURN;
@ -118,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;
@ -159,5 +158,5 @@ INSERT INTO exchange.account_merges
END $$; END $$;
COMMENT ON FUNCTION exchange_do_reserve_purse(BYTEA, BYTEA, INT8, INT8, INT8, BYTEA, BOOLEAN, INT8, INT4, BYTEA, BYTEA) COMMENT ON FUNCTION exchange_do_reserve_purse(BYTEA, BYTEA, INT8, INT8, INT8, BYTEA, BOOLEAN, taler_amount, BYTEA, BYTEA)
IS 'Create a purse for a reserve.'; IS 'Create a purse for a reserve.';

View File

@ -19,8 +19,7 @@ CREATE OR REPLACE FUNCTION exchange_do_batch_reserves_in_insert(
IN in_reserve_expiration INT8, IN in_reserve_expiration INT8,
IN in_reserve_pub BYTEA, IN in_reserve_pub BYTEA,
IN in_wire_ref INT8, IN in_wire_ref INT8,
IN in_credit_val INT8, IN in_credit taler_amount,
IN in_credit_frac INT4,
IN in_exchange_account_name VARCHAR, IN in_exchange_account_name VARCHAR,
IN in_execution_date INT8, IN in_execution_date INT8,
IN in_wire_source_h_payto BYTEA, IN in_wire_source_h_payto BYTEA,
@ -42,14 +41,12 @@ BEGIN
INSERT INTO reserves INSERT INTO reserves
(reserve_pub (reserve_pub
,current_balance_val ,current_balance
,current_balance_frac
,expiration_date ,expiration_date
,gc_date) ,gc_date)
VALUES VALUES
(in_reserve_pub (in_reserve_pub
,in_credit_val ,in_credit
,in_credit_frac
,in_reserve_expiration ,in_reserve_expiration
,in_gc_date) ,in_gc_date)
ON CONFLICT DO NOTHING ON CONFLICT DO NOTHING
@ -67,8 +64,8 @@ BEGIN
VALUES VALUES
(in_reserve_pub (in_reserve_pub
,in_wire_ref ,in_wire_ref
,in_credit_val ,in_credit.val
,in_credit_frac ,in_credit.frac
,in_exchange_account_name ,in_exchange_account_name
,in_wire_source_h_payto ,in_wire_source_h_payto
,in_execution_date) ,in_execution_date)
@ -90,8 +87,7 @@ CREATE OR REPLACE FUNCTION exchange_do_batch2_reserves_insert(
IN in_reserve_expiration INT8, IN in_reserve_expiration INT8,
IN in0_reserve_pub BYTEA, IN in0_reserve_pub BYTEA,
IN in0_wire_ref INT8, IN in0_wire_ref INT8,
IN in0_credit_val INT8, IN in0_credit taler_amount,
IN in0_credit_frac INT4,
IN in0_exchange_account_name VARCHAR, IN in0_exchange_account_name VARCHAR,
IN in0_execution_date INT8, IN in0_execution_date INT8,
IN in0_wire_source_h_payto BYTEA, IN in0_wire_source_h_payto BYTEA,
@ -99,8 +95,7 @@ CREATE OR REPLACE FUNCTION exchange_do_batch2_reserves_insert(
IN in0_notify TEXT, IN in0_notify TEXT,
IN in1_reserve_pub BYTEA, IN in1_reserve_pub BYTEA,
IN in1_wire_ref INT8, IN in1_wire_ref INT8,
IN in1_credit_val INT8, IN in1_credit taler_amount,
IN in1_credit_frac INT4,
IN in1_exchange_account_name VARCHAR, IN in1_exchange_account_name VARCHAR,
IN in1_execution_date INT8, IN in1_execution_date INT8,
IN in1_wire_source_h_payto BYTEA, IN in1_wire_source_h_payto BYTEA,
@ -138,19 +133,16 @@ BEGIN
WITH reserve_changes AS ( WITH reserve_changes AS (
INSERT INTO reserves INSERT INTO reserves
(reserve_pub (reserve_pub
,current_balance_val ,current_balance
,current_balance_frac
,expiration_date ,expiration_date
,gc_date) ,gc_date)
VALUES VALUES
(in0_reserve_pub (in0_reserve_pub
,in0_credit_val ,in0_credit
,in0_credit_frac
,in_reserve_expiration ,in_reserve_expiration
,in_gc_date), ,in_gc_date),
(in1_reserve_pub (in1_reserve_pub
,in1_credit_val ,in1_credit
,in1_credit_frac
,in_reserve_expiration ,in_reserve_expiration
,in_gc_date) ,in_gc_date)
ON CONFLICT DO NOTHING ON CONFLICT DO NOTHING
@ -200,15 +192,15 @@ BEGIN
VALUES VALUES
(in0_reserve_pub (in0_reserve_pub
,in0_wire_ref ,in0_wire_ref
,in0_credit_val ,in0_credit.val
,in0_credit_frac ,in0_credit.frac
,in0_exchange_account_name ,in0_exchange_account_name
,in0_wire_source_h_payto ,in0_wire_source_h_payto
,in0_execution_date), ,in0_execution_date),
(in1_reserve_pub (in1_reserve_pub
,in1_wire_ref ,in1_wire_ref
,in1_credit_val ,in1_credit.val
,in1_credit_frac ,in1_credit.frac
,in1_exchange_account_name ,in1_exchange_account_name
,in1_wire_source_h_payto ,in1_wire_source_h_payto
,in1_execution_date) ,in1_execution_date)
@ -261,8 +253,7 @@ CREATE OR REPLACE FUNCTION exchange_do_batch4_reserves_insert(
IN in_reserve_expiration INT8, IN in_reserve_expiration INT8,
IN in0_reserve_pub BYTEA, IN in0_reserve_pub BYTEA,
IN in0_wire_ref INT8, IN in0_wire_ref INT8,
IN in0_credit_val INT8, IN in0_credit taler_amount,
IN in0_credit_frac INT4,
IN in0_exchange_account_name VARCHAR, IN in0_exchange_account_name VARCHAR,
IN in0_execution_date INT8, IN in0_execution_date INT8,
IN in0_wire_source_h_payto BYTEA, IN in0_wire_source_h_payto BYTEA,
@ -270,8 +261,7 @@ CREATE OR REPLACE FUNCTION exchange_do_batch4_reserves_insert(
IN in0_notify TEXT, IN in0_notify TEXT,
IN in1_reserve_pub BYTEA, IN in1_reserve_pub BYTEA,
IN in1_wire_ref INT8, IN in1_wire_ref INT8,
IN in1_credit_val INT8, IN in1_credit taler_amount,
IN in1_credit_frac INT4,
IN in1_exchange_account_name VARCHAR, IN in1_exchange_account_name VARCHAR,
IN in1_execution_date INT8, IN in1_execution_date INT8,
IN in1_wire_source_h_payto BYTEA, IN in1_wire_source_h_payto BYTEA,
@ -279,8 +269,7 @@ CREATE OR REPLACE FUNCTION exchange_do_batch4_reserves_insert(
IN in1_notify TEXT, IN in1_notify TEXT,
IN in2_reserve_pub BYTEA, IN in2_reserve_pub BYTEA,
IN in2_wire_ref INT8, IN in2_wire_ref INT8,
IN in2_credit_val INT8, IN in2_credit taler_amount,
IN in2_credit_frac INT4,
IN in2_exchange_account_name VARCHAR, IN in2_exchange_account_name VARCHAR,
IN in2_execution_date INT8, IN in2_execution_date INT8,
IN in2_wire_source_h_payto BYTEA, IN in2_wire_source_h_payto BYTEA,
@ -288,8 +277,7 @@ CREATE OR REPLACE FUNCTION exchange_do_batch4_reserves_insert(
IN in2_notify TEXT, IN in2_notify TEXT,
IN in3_reserve_pub BYTEA, IN in3_reserve_pub BYTEA,
IN in3_wire_ref INT8, IN in3_wire_ref INT8,
IN in3_credit_val INT8, IN in3_credit taler_amount,
IN in3_credit_frac INT4,
IN in3_exchange_account_name VARCHAR, IN in3_exchange_account_name VARCHAR,
IN in3_execution_date INT8, IN in3_execution_date INT8,
IN in3_wire_source_h_payto BYTEA, IN in3_wire_source_h_payto BYTEA,
@ -337,29 +325,24 @@ BEGIN
WITH reserve_changes AS ( WITH reserve_changes AS (
INSERT INTO reserves INSERT INTO reserves
(reserve_pub (reserve_pub
,current_balance_val ,current_balance
,current_balance_frac
,expiration_date ,expiration_date
,gc_date) ,gc_date)
VALUES VALUES
(in0_reserve_pub (in0_reserve_pub
,in0_credit_val ,in0_credit
,in0_credit_frac
,in_reserve_expiration ,in_reserve_expiration
,in_gc_date), ,in_gc_date),
(in1_reserve_pub (in1_reserve_pub
,in1_credit_val ,in1_credit
,in1_credit_frac
,in_reserve_expiration ,in_reserve_expiration
,in_gc_date), ,in_gc_date),
(in2_reserve_pub (in2_reserve_pub
,in2_credit_val ,in2_credit
,in2_credit_frac
,in_reserve_expiration ,in_reserve_expiration
,in_gc_date), ,in_gc_date),
(in3_reserve_pub (in3_reserve_pub
,in3_credit_val ,in3_credit
,in3_credit_frac
,in_reserve_expiration ,in_reserve_expiration
,in_gc_date) ,in_gc_date)
ON CONFLICT DO NOTHING ON CONFLICT DO NOTHING
@ -425,29 +408,29 @@ BEGIN
VALUES VALUES
(in0_reserve_pub (in0_reserve_pub
,in0_wire_ref ,in0_wire_ref
,in0_credit_val ,in0_credit.val
,in0_credit_frac ,in0_credit.frac
,in0_exchange_account_name ,in0_exchange_account_name
,in0_wire_source_h_payto ,in0_wire_source_h_payto
,in0_execution_date), ,in0_execution_date),
(in1_reserve_pub (in1_reserve_pub
,in1_wire_ref ,in1_wire_ref
,in1_credit_val ,in1_credit.val
,in1_credit_frac ,in1_credit.frac
,in1_exchange_account_name ,in1_exchange_account_name
,in1_wire_source_h_payto ,in1_wire_source_h_payto
,in1_execution_date), ,in1_execution_date),
(in2_reserve_pub (in2_reserve_pub
,in2_wire_ref ,in2_wire_ref
,in2_credit_val ,in2_credit.val
,in2_credit_frac ,in2_credit.frac
,in2_exchange_account_name ,in2_exchange_account_name
,in2_wire_source_h_payto ,in2_wire_source_h_payto
,in2_execution_date), ,in2_execution_date),
(in3_reserve_pub (in3_reserve_pub
,in3_wire_ref ,in3_wire_ref
,in3_credit_val ,in3_credit.val
,in3_credit_frac ,in3_credit.frac
,in3_exchange_account_name ,in3_exchange_account_name
,in3_wire_source_h_payto ,in3_wire_source_h_payto
,in3_execution_date) ,in3_execution_date)
@ -522,8 +505,7 @@ CREATE OR REPLACE FUNCTION exchange_do_batch8_reserves_insert(
IN in_reserve_expiration INT8, IN in_reserve_expiration INT8,
IN in0_reserve_pub BYTEA, IN in0_reserve_pub BYTEA,
IN in0_wire_ref INT8, IN in0_wire_ref INT8,
IN in0_credit_val INT8, IN in0_credit taler_amount,
IN in0_credit_frac INT4,
IN in0_exchange_account_name VARCHAR, IN in0_exchange_account_name VARCHAR,
IN in0_execution_date INT8, IN in0_execution_date INT8,
IN in0_wire_source_h_payto BYTEA, IN in0_wire_source_h_payto BYTEA,
@ -531,8 +513,7 @@ CREATE OR REPLACE FUNCTION exchange_do_batch8_reserves_insert(
IN in0_notify TEXT, IN in0_notify TEXT,
IN in1_reserve_pub BYTEA, IN in1_reserve_pub BYTEA,
IN in1_wire_ref INT8, IN in1_wire_ref INT8,
IN in1_credit_val INT8, IN in1_credit taler_amount,
IN in1_credit_frac INT4,
IN in1_exchange_account_name VARCHAR, IN in1_exchange_account_name VARCHAR,
IN in1_execution_date INT8, IN in1_execution_date INT8,
IN in1_wire_source_h_payto BYTEA, IN in1_wire_source_h_payto BYTEA,
@ -540,8 +521,7 @@ CREATE OR REPLACE FUNCTION exchange_do_batch8_reserves_insert(
IN in1_notify TEXT, IN in1_notify TEXT,
IN in2_reserve_pub BYTEA, IN in2_reserve_pub BYTEA,
IN in2_wire_ref INT8, IN in2_wire_ref INT8,
IN in2_credit_val INT8, IN in2_credit taler_amount,
IN in2_credit_frac INT4,
IN in2_exchange_account_name VARCHAR, IN in2_exchange_account_name VARCHAR,
IN in2_execution_date INT8, IN in2_execution_date INT8,
IN in2_wire_source_h_payto BYTEA, IN in2_wire_source_h_payto BYTEA,
@ -549,8 +529,7 @@ CREATE OR REPLACE FUNCTION exchange_do_batch8_reserves_insert(
IN in2_notify TEXT, IN in2_notify TEXT,
IN in3_reserve_pub BYTEA, IN in3_reserve_pub BYTEA,
IN in3_wire_ref INT8, IN in3_wire_ref INT8,
IN in3_credit_val INT8, IN in3_credit taler_amount,
IN in3_credit_frac INT4,
IN in3_exchange_account_name VARCHAR, IN in3_exchange_account_name VARCHAR,
IN in3_execution_date INT8, IN in3_execution_date INT8,
IN in3_wire_source_h_payto BYTEA, IN in3_wire_source_h_payto BYTEA,
@ -558,8 +537,7 @@ CREATE OR REPLACE FUNCTION exchange_do_batch8_reserves_insert(
IN in3_notify TEXT, IN in3_notify TEXT,
IN in4_reserve_pub BYTEA, IN in4_reserve_pub BYTEA,
IN in4_wire_ref INT8, IN in4_wire_ref INT8,
IN in4_credit_val INT8, IN in4_credit taler_amount,
IN in4_credit_frac INT4,
IN in4_exchange_account_name VARCHAR, IN in4_exchange_account_name VARCHAR,
IN in4_execution_date INT8, IN in4_execution_date INT8,
IN in4_wire_source_h_payto BYTEA, IN in4_wire_source_h_payto BYTEA,
@ -567,8 +545,7 @@ CREATE OR REPLACE FUNCTION exchange_do_batch8_reserves_insert(
IN in4_notify TEXT, IN in4_notify TEXT,
IN in5_reserve_pub BYTEA, IN in5_reserve_pub BYTEA,
IN in5_wire_ref INT8, IN in5_wire_ref INT8,
IN in5_credit_val INT8, IN in5_credit taler_amount,
IN in5_credit_frac INT4,
IN in5_exchange_account_name VARCHAR, IN in5_exchange_account_name VARCHAR,
IN in5_execution_date INT8, IN in5_execution_date INT8,
IN in5_wire_source_h_payto BYTEA, IN in5_wire_source_h_payto BYTEA,
@ -576,8 +553,7 @@ CREATE OR REPLACE FUNCTION exchange_do_batch8_reserves_insert(
IN in5_notify TEXT, IN in5_notify TEXT,
IN in6_reserve_pub BYTEA, IN in6_reserve_pub BYTEA,
IN in6_wire_ref INT8, IN in6_wire_ref INT8,
IN in6_credit_val INT8, IN in6_credit taler_amount,
IN in6_credit_frac INT4,
IN in6_exchange_account_name VARCHAR, IN in6_exchange_account_name VARCHAR,
IN in6_execution_date INT8, IN in6_execution_date INT8,
IN in6_wire_source_h_payto BYTEA, IN in6_wire_source_h_payto BYTEA,
@ -585,8 +561,7 @@ CREATE OR REPLACE FUNCTION exchange_do_batch8_reserves_insert(
IN in6_notify TEXT, IN in6_notify TEXT,
IN in7_reserve_pub BYTEA, IN in7_reserve_pub BYTEA,
IN in7_wire_ref INT8, IN in7_wire_ref INT8,
IN in7_credit_val INT8, IN in7_credit taler_amount,
IN in7_credit_frac INT4,
IN in7_exchange_account_name VARCHAR, IN in7_exchange_account_name VARCHAR,
IN in7_execution_date INT8, IN in7_execution_date INT8,
IN in7_wire_source_h_payto BYTEA, IN in7_wire_source_h_payto BYTEA,
@ -657,49 +632,40 @@ BEGIN
WITH reserve_changes AS ( WITH reserve_changes AS (
INSERT INTO reserves INSERT INTO reserves
(reserve_pub (reserve_pub
,current_balance_val ,current_balance
,current_balance_frac
,expiration_date ,expiration_date
,gc_date) ,gc_date)
VALUES VALUES
(in0_reserve_pub (in0_reserve_pub
,in0_credit_val ,in0_credit
,in0_credit_frac
,in_reserve_expiration ,in_reserve_expiration
,in_gc_date), ,in_gc_date),
(in1_reserve_pub (in1_reserve_pub
,in1_credit_val ,in1_credit
,in1_credit_frac
,in_reserve_expiration ,in_reserve_expiration
,in_gc_date), ,in_gc_date),
(in2_reserve_pub (in2_reserve_pub
,in2_credit_val ,in2_credit
,in2_credit_frac
,in_reserve_expiration ,in_reserve_expiration
,in_gc_date), ,in_gc_date),
(in3_reserve_pub (in3_reserve_pub
,in3_credit_val ,in3_credit
,in3_credit_frac
,in_reserve_expiration ,in_reserve_expiration
,in_gc_date), ,in_gc_date),
(in4_reserve_pub (in4_reserve_pub
,in4_credit_val ,in4_credit
,in4_credit_frac
,in_reserve_expiration ,in_reserve_expiration
,in_gc_date), ,in_gc_date),
(in5_reserve_pub (in5_reserve_pub
,in5_credit_val ,in5_credit
,in5_credit_frac
,in_reserve_expiration ,in_reserve_expiration
,in_gc_date), ,in_gc_date),
(in6_reserve_pub (in6_reserve_pub
,in6_credit_val ,in6_credit
,in6_credit_frac
,in_reserve_expiration ,in_reserve_expiration
,in_gc_date), ,in_gc_date),
(in7_reserve_pub (in7_reserve_pub
,in7_credit_val ,in7_credit
,in7_credit_frac
,in_reserve_expiration ,in_reserve_expiration
,in_gc_date) ,in_gc_date)
ON CONFLICT DO NOTHING ON CONFLICT DO NOTHING
@ -802,57 +768,57 @@ BEGIN
VALUES VALUES
(in0_reserve_pub (in0_reserve_pub
,in0_wire_ref ,in0_wire_ref
,in0_credit_val ,in0_credit.val
,in0_credit_frac ,in0_credit.frac
,in0_exchange_account_name ,in0_exchange_account_name
,in0_wire_source_h_payto ,in0_wire_source_h_payto
,in0_execution_date), ,in0_execution_date),
(in1_reserve_pub (in1_reserve_pub
,in1_wire_ref ,in1_wire_ref
,in1_credit_val ,in1_credit.val
,in1_credit_frac ,in1_credit.frac
,in1_exchange_account_name ,in1_exchange_account_name
,in1_wire_source_h_payto ,in1_wire_source_h_payto
,in1_execution_date), ,in1_execution_date),
(in2_reserve_pub (in2_reserve_pub
,in2_wire_ref ,in2_wire_ref
,in2_credit_val ,in2_credit.val
,in2_credit_frac ,in2_credit.frac
,in2_exchange_account_name ,in2_exchange_account_name
,in2_wire_source_h_payto ,in2_wire_source_h_payto
,in2_execution_date), ,in2_execution_date),
(in3_reserve_pub (in3_reserve_pub
,in3_wire_ref ,in3_wire_ref
,in3_credit_val ,in3_credit.val
,in3_credit_frac ,in3_credit.frac
,in3_exchange_account_name ,in3_exchange_account_name
,in3_wire_source_h_payto ,in3_wire_source_h_payto
,in3_execution_date), ,in3_execution_date),
(in4_reserve_pub (in4_reserve_pub
,in4_wire_ref ,in4_wire_ref
,in4_credit_val ,in4_credit.val
,in4_credit_frac ,in4_credit.frac
,in4_exchange_account_name ,in4_exchange_account_name
,in4_wire_source_h_payto ,in4_wire_source_h_payto
,in4_execution_date), ,in4_execution_date),
(in5_reserve_pub (in5_reserve_pub
,in5_wire_ref ,in5_wire_ref
,in5_credit_val ,in5_credit.val
,in5_credit_frac ,in5_credit.frac
,in5_exchange_account_name ,in5_exchange_account_name
,in5_wire_source_h_payto ,in5_wire_source_h_payto
,in5_execution_date), ,in5_execution_date),
(in6_reserve_pub (in6_reserve_pub
,in6_wire_ref ,in6_wire_ref
,in6_credit_val ,in6_credit.val
,in6_credit_frac ,in6_credit.frac
,in6_exchange_account_name ,in6_exchange_account_name
,in6_wire_source_h_payto ,in6_wire_source_h_payto
,in6_execution_date), ,in6_execution_date),
(in7_reserve_pub (in7_reserve_pub
,in7_wire_ref ,in7_wire_ref
,in7_credit_val ,in7_credit.val
,in7_credit_frac ,in7_credit.frac
,in7_exchange_account_name ,in7_exchange_account_name
,in7_wire_source_h_payto ,in7_wire_source_h_payto
,in7_execution_date) ,in7_execution_date)

View File

@ -17,8 +17,7 @@
CREATE OR REPLACE FUNCTION exchange_do_withdraw( CREATE OR REPLACE FUNCTION exchange_do_withdraw(
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, IN h_denom_pub BYTEA,
IN rpub BYTEA, IN rpub BYTEA,
IN reserve_sig BYTEA, IN reserve_sig BYTEA,
@ -38,8 +37,7 @@ AS $$
DECLARE DECLARE
reserve_gc INT8; reserve_gc INT8;
denom_serial INT8; denom_serial INT8;
reserve_val INT8; reserve taler_amount;
reserve_frac INT4;
reserve_birthday INT4; reserve_birthday INT4;
not_before date; not_before date;
BEGIN BEGIN
@ -68,14 +66,13 @@ END IF;
SELECT SELECT
current_balance_val current_balance
,current_balance_frac
,gc_date ,gc_date
,birthday ,birthday
,reserve_uuid ,reserve_uuid
INTO INTO
reserve_val reserve.val
,reserve_frac ,reserve.frac
,reserve_gc ,reserve_gc
,reserve_birthday ,reserve_birthday
,ruuid ,ruuid
@ -133,8 +130,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
@ -147,21 +144,21 @@ THEN
END IF; END IF;
-- Check reserve balance is sufficient. -- Check reserve balance is sufficient.
IF (reserve_val > amount_val) IF (reserve.val > amount.val)
THEN THEN
IF (reserve_frac >= amount_frac) IF (reserve.frac >= amount.frac)
THEN THEN
reserve_val=reserve_val - amount_val; reserve.val=reserve.val - amount.val;
reserve_frac=reserve_frac - amount_frac; reserve.frac=reserve.frac - amount.frac;
ELSE ELSE
reserve_val=reserve_val - amount_val - 1; reserve.val=reserve.val - amount.val - 1;
reserve_frac=reserve_frac + 100000000 - amount_frac; reserve.frac=reserve.frac + 100000000 - amount.frac;
END IF; END IF;
ELSE ELSE
IF (reserve_val = amount_val) AND (reserve_frac >= amount_frac) IF (reserve.val = amount.val) AND (reserve.frac >= amount.frac)
THEN THEN
reserve_val=0; reserve.val=0;
reserve_frac=reserve_frac - amount_frac; reserve.frac=reserve.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
@ -176,8 +173,7 @@ min_reserve_gc=GREATEST(min_reserve_gc,reserve_gc);
-- Update reserve balance. -- Update reserve balance.
UPDATE reserves SET UPDATE reserves SET
gc_date=min_reserve_gc gc_date=min_reserve_gc
,current_balance_val=reserve_val ,current_balance=reserve
,current_balance_frac=reserve_frac
WHERE WHERE
reserves.reserve_pub=rpub; reserves.reserve_pub=rpub;
@ -222,7 +218,6 @@ END IF;
END $$; END $$;
COMMENT ON FUNCTION exchange_do_withdraw(BYTEA, taler_amount, BYTEA, BYTEA, BYTEA, BYTEA, BYTEA, INT8, INT8, BOOLEAN)
COMMENT ON FUNCTION exchange_do_withdraw(BYTEA, INT8, INT4, BYTEA, BYTEA, BYTEA, BYTEA, BYTEA, INT8, INT8, BOOLEAN)
IS 'Checks whether the reserve has sufficient balance for a withdraw operation (or the request is repeated and was previously approved) and if the age requirements are formally met. If so updates the database with the result'; IS 'Checks whether the reserve has sufficient balance for a withdraw operation (or the request is repeated and was previously approved) and if the age requirements are formally met. If so updates the database with the result';

View File

@ -41,7 +41,8 @@ TEH_PG_do_batch_withdraw_insert (
NULL == nonce NULL == nonce
? GNUNET_PQ_query_param_null () ? GNUNET_PQ_query_param_null ()
: GNUNET_PQ_query_param_auto_from_type (nonce), : GNUNET_PQ_query_param_auto_from_type (nonce),
TALER_PQ_query_param_amount (&collectable->amount_with_fee), TALER_PQ_query_param_amount_tuple (pg->conn,
&collectable->amount_with_fee),
GNUNET_PQ_query_param_auto_from_type (&collectable->denom_pub_hash), GNUNET_PQ_query_param_auto_from_type (&collectable->denom_pub_hash),
GNUNET_PQ_query_param_uint64 (&ruuid), GNUNET_PQ_query_param_uint64 (&ruuid),
GNUNET_PQ_query_param_auto_from_type (&collectable->reserve_sig), GNUNET_PQ_query_param_auto_from_type (&collectable->reserve_sig),
@ -69,7 +70,7 @@ TEH_PG_do_batch_withdraw_insert (
",out_conflict AS conflict" ",out_conflict AS conflict"
",out_nonce_reuse AS nonce_reuse" ",out_nonce_reuse AS nonce_reuse"
" FROM exchange_do_batch_withdraw_insert" " FROM exchange_do_batch_withdraw_insert"
" ($1,$2,$3,$4,$5,$6,$7,$8,$9);"); " ($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_batch_withdraw_insert", "call_batch_withdraw_insert",
params, params,

View File

@ -46,7 +46,8 @@ TEH_PG_do_withdraw (
NULL == nonce NULL == nonce
? GNUNET_PQ_query_param_null () ? GNUNET_PQ_query_param_null ()
: GNUNET_PQ_query_param_auto_from_type (nonce), : GNUNET_PQ_query_param_auto_from_type (nonce),
TALER_PQ_query_param_amount (&collectable->amount_with_fee), TALER_PQ_query_param_amount_tuple (pg->conn,
&collectable->amount_with_fee),
GNUNET_PQ_query_param_auto_from_type (&collectable->denom_pub_hash), GNUNET_PQ_query_param_auto_from_type (&collectable->denom_pub_hash),
GNUNET_PQ_query_param_auto_from_type (&collectable->reserve_pub), GNUNET_PQ_query_param_auto_from_type (&collectable->reserve_pub),
GNUNET_PQ_query_param_auto_from_type (&collectable->reserve_sig), GNUNET_PQ_query_param_auto_from_type (&collectable->reserve_sig),
@ -83,7 +84,7 @@ TEH_PG_do_withdraw (
",allowed_maximum_age" ",allowed_maximum_age"
",ruuid" ",ruuid"
" FROM exchange_do_withdraw" " FROM exchange_do_withdraw"
" ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11);"); " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10);");
gc = GNUNET_TIME_absolute_to_timestamp ( gc = GNUNET_TIME_absolute_to_timestamp (
GNUNET_TIME_absolute_add (now.abs_time, GNUNET_TIME_absolute_add (now.abs_time,
pg->legal_reserve_expiration_time)); pg->legal_reserve_expiration_time));

View File

@ -84,8 +84,9 @@ reserve_expired_cb (void *cls,
&account_details), &account_details),
GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
&reserve_pub), &reserve_pub),
TALER_PQ_RESULT_SPEC_AMOUNT ("current_balance", TALER_PQ_result_spec_amount_tuple ("current_balance",
&remaining_balance), pg->currency,
&remaining_balance),
GNUNET_PQ_result_spec_end GNUNET_PQ_result_spec_end
}; };
@ -137,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 "
") " ") "
@ -145,8 +146,7 @@ TEH_PG_get_expired_reserves (void *cls,
" ed.expiration_date " " ed.expiration_date "
" ,payto_uri AS account_details " " ,payto_uri AS account_details "
" ,ed.reserve_pub " " ,ed.reserve_pub "
" ,current_balance_val " " ,current_balance "
" ,current_balance_frac "
"FROM ( " "FROM ( "
" SELECT " " SELECT "
" * " " * "

View File

@ -36,16 +36,16 @@ TEH_PG_get_reserve_balance (void *cls,
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 ("current_balance", TALER_PQ_result_spec_amount_tuple ("current_balance",
balance), pg->currency,
balance),
GNUNET_PQ_result_spec_end GNUNET_PQ_result_spec_end
}; };
PREPARE (pg, PREPARE (pg,
"get_reserve_balance", "get_reserve_balance",
"SELECT" "SELECT"
" current_balance_val" " current_balance"
",current_balance_frac"
" FROM reserves" " FROM reserves"
" WHERE reserve_pub=$1;"); " WHERE reserve_pub=$1;");
return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,

View File

@ -35,8 +35,9 @@ TEH_PG_reserves_get (void *cls,
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 ("current_balance", TALER_PQ_result_spec_amount_tuple ("current_balance",
&reserve->balance), pg->currency,
&reserve->balance),
GNUNET_PQ_result_spec_timestamp ("expiration_date", GNUNET_PQ_result_spec_timestamp ("expiration_date",
&reserve->expiry), &reserve->expiry),
GNUNET_PQ_result_spec_timestamp ("gc_date", GNUNET_PQ_result_spec_timestamp ("gc_date",
@ -47,8 +48,7 @@ TEH_PG_reserves_get (void *cls,
PREPARE (pg, PREPARE (pg,
"reserves_get", "reserves_get",
"SELECT" "SELECT"
" current_balance_val" " current_balance"
",current_balance_frac"
",expiration_date" ",expiration_date"
",gc_date" ",gc_date"
" FROM reserves" " FROM reserves"

View File

@ -100,7 +100,7 @@ struct ReserveRecord
#define RR_QUERY_PARAM(rr,index) \ #define RR_QUERY_PARAM(rr,index) \
GNUNET_PQ_query_param_auto_from_type (rr[index].reserve->reserve_pub), \ GNUNET_PQ_query_param_auto_from_type (rr[index].reserve->reserve_pub), \
GNUNET_PQ_query_param_uint64 (&rr[index].reserve->wire_reference), \ GNUNET_PQ_query_param_uint64 (&rr[index].reserve->wire_reference), \
TALER_PQ_query_param_amount (rr[index].reserve->balance), \ TALER_PQ_query_param_amount_tuple (pg->conn, rr[index].reserve->balance), \
GNUNET_PQ_query_param_string (rr[index].reserve->exchange_account_name), \ GNUNET_PQ_query_param_string (rr[index].reserve->exchange_account_name), \
GNUNET_PQ_query_param_timestamp (&rr[index].reserve->execution_time), \ GNUNET_PQ_query_param_timestamp (&rr[index].reserve->execution_time), \
GNUNET_PQ_query_param_auto_from_type (&rr[index].h_payto), \ GNUNET_PQ_query_param_auto_from_type (&rr[index].h_payto), \
@ -154,7 +154,7 @@ insert1 (struct PostgresClosure *pg,
" transaction_duplicate0 AS transaction_duplicate0" " transaction_duplicate0 AS transaction_duplicate0"
",ruuid0 AS reserve_uuid0" ",ruuid0 AS reserve_uuid0"
" FROM exchange_do_batch_reserves_in_insert" " FROM exchange_do_batch_reserves_in_insert"
" ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11);"); " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10);");
qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"batch1_reserve_create", "batch1_reserve_create",
params, params,
@ -214,7 +214,7 @@ insert2 (struct PostgresClosure *pg,
",ruuid0 AS reserve_uuid0" ",ruuid0 AS reserve_uuid0"
",ruuid1 AS reserve_uuid1" ",ruuid1 AS reserve_uuid1"
" FROM exchange_do_batch2_reserves_insert" " FROM exchange_do_batch2_reserves_insert"
" ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20);"); " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18);");
qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"batch2_reserve_create", "batch2_reserve_create",
params, params,
@ -285,7 +285,7 @@ insert4 (struct PostgresClosure *pg,
",ruuid2 AS reserve_uuid2" ",ruuid2 AS reserve_uuid2"
",ruuid3 AS reserve_uuid3" ",ruuid3 AS reserve_uuid3"
" FROM exchange_do_batch4_reserves_insert" " FROM exchange_do_batch4_reserves_insert"
" ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33,$34,$35,$36,$37,$38);"); " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33,$34);");
qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"batch4_reserve_create", "batch4_reserve_create",
params, params,
@ -373,7 +373,7 @@ insert8 (struct PostgresClosure *pg,
",ruuid6 AS reserve_uuid6" ",ruuid6 AS reserve_uuid6"
",ruuid7 AS reserve_uuid7" ",ruuid7 AS reserve_uuid7"
" FROM exchange_do_batch8_reserves_insert" " FROM exchange_do_batch8_reserves_insert"
" ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33,$34,$35,$36,$37,$38,$39, $40, $41,$42,$43,$44,$45,$46,$47,$48,$49,$50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$60,$61,$62,$63,$64,$65,$66,$67,$68,$69,$70,$71,$72,$73,$74);"); " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33,$34,$35,$36,$37,$38,$39, $40, $41,$42,$43,$44,$45,$46,$47,$48,$49,$50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$60,$61,$62,$63,$64,$65,$66);");
qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"batch8_reserve_create", "batch8_reserve_create",
@ -537,7 +537,8 @@ transact (
GNUNET_PQ_query_param_auto_from_type (rr[i].reserve->reserve_pub), GNUNET_PQ_query_param_auto_from_type (rr[i].reserve->reserve_pub),
GNUNET_PQ_query_param_timestamp (&reserve_expiration), GNUNET_PQ_query_param_timestamp (&reserve_expiration),
GNUNET_PQ_query_param_uint64 (&rr[i].reserve->wire_reference), GNUNET_PQ_query_param_uint64 (&rr[i].reserve->wire_reference),
TALER_PQ_query_param_amount (rr[i].reserve->balance), TALER_PQ_query_param_amount_tuple (pg->conn,
rr[i].reserve->balance),
GNUNET_PQ_query_param_string (rr[i].reserve->exchange_account_name), GNUNET_PQ_query_param_string (rr[i].reserve->exchange_account_name),
GNUNET_PQ_query_param_auto_from_type (&rr[i].h_payto), GNUNET_PQ_query_param_auto_from_type (&rr[i].h_payto),
GNUNET_PQ_query_param_string (rr[i].notify_s), GNUNET_PQ_query_param_string (rr[i].notify_s),
@ -859,7 +860,8 @@ TEH_PG_reserves_in_insertN (
GNUNET_PQ_query_param_auto_from_type (reserve_pubs[i]), GNUNET_PQ_query_param_auto_from_type (reserve_pubs[i]),
GNUNET_PQ_query_param_timestamp (&reserve_expiration), GNUNET_PQ_query_param_timestamp (&reserve_expiration),
GNUNET_PQ_query_param_uint64 (&wire_reference[i]), GNUNET_PQ_query_param_uint64 (&wire_reference[i]),
TALER_PQ_query_param_amount (balances[i]), TALER_PQ_query_param_amount_tuple (pg->conn,
balances[i]),
GNUNET_PQ_query_param_string (exchange_account_names[i]), GNUNET_PQ_query_param_string (exchange_account_names[i]),
GNUNET_PQ_query_param_auto_from_type (h_paytos[i]), GNUNET_PQ_query_param_auto_from_type (h_paytos[i]),
GNUNET_PQ_query_param_string (notify_s[i]), GNUNET_PQ_query_param_string (notify_s[i]),

View File

@ -33,7 +33,8 @@ TEH_PG_reserves_update (void *cls,
struct GNUNET_PQ_QueryParam params[] = { struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_timestamp (&reserve->expiry), GNUNET_PQ_query_param_timestamp (&reserve->expiry),
GNUNET_PQ_query_param_timestamp (&reserve->gc), GNUNET_PQ_query_param_timestamp (&reserve->gc),
TALER_PQ_query_param_amount (&reserve->balance), TALER_PQ_query_param_amount_tuple (pg->conn,
&reserve->balance),
GNUNET_PQ_query_param_auto_from_type (&reserve->pub), GNUNET_PQ_query_param_auto_from_type (&reserve->pub),
GNUNET_PQ_query_param_end GNUNET_PQ_query_param_end
}; };
@ -44,9 +45,8 @@ TEH_PG_reserves_update (void *cls,
" SET" " SET"
" expiration_date=$1" " expiration_date=$1"
",gc_date=$2" ",gc_date=$2"
",current_balance_val=$3" ",current_balance=$3"
",current_balance_frac=$4" " WHERE reserve_pub=$4;");
" WHERE reserve_pub=$5;");
return GNUNET_PQ_eval_prepared_non_select (pg->conn, return GNUNET_PQ_eval_prepared_non_select (pg->conn,
"reserve_update", "reserve_update",
params); params);

View File

@ -39,8 +39,9 @@ TEH_PG_select_reserve_close_info (
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 ("current_balance", TALER_PQ_result_spec_amount_tuple ("current_balance",
balance), pg->currency,
balance),
GNUNET_PQ_result_spec_string ("payto_uri", GNUNET_PQ_result_spec_string ("payto_uri",
payto_uri), payto_uri),
GNUNET_PQ_result_spec_end GNUNET_PQ_result_spec_end
@ -49,8 +50,7 @@ TEH_PG_select_reserve_close_info (
PREPARE (pg, PREPARE (pg,
"select_reserve_close_info", "select_reserve_close_info",
"SELECT " "SELECT "
" r.current_balance_val" " r.current_balance"
",r.current_balance_frac"
",wt.payto_uri" ",wt.payto_uri"
" FROM reserves r" " FROM reserves r"
" LEFT JOIN reserves_in ri USING (reserve_pub)" " LEFT JOIN reserves_in ri USING (reserve_pub)"

View File

@ -293,6 +293,7 @@ TEH_PG_internal_setup (struct PostgresClosure *pg)
NULL); NULL);
if (NULL == db_conn) if (NULL == db_conn)
return GNUNET_SYSERR; return GNUNET_SYSERR;
pg->prep_gen++; pg->prep_gen++;
pg->conn = db_conn; pg->conn = db_conn;
} }
@ -778,6 +779,12 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
plugin->batch_ensure_coin_known plugin->batch_ensure_coin_known
= &TEH_PG_batch_ensure_coin_known; = &TEH_PG_batch_ensure_coin_known;
if (GNUNET_OK != TALER_PQ_load_oids_for_composite_types (pg->conn))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to load OIDs for composite types\n");
}
return plugin; return plugin;
} }

View File

@ -46,7 +46,6 @@ TALER_EXCHANGEDB_plugin_load (const struct GNUNET_CONFIGURATION_Handle *cfg);
void void
TALER_EXCHANGEDB_plugin_unload (struct TALER_EXCHANGEDB_Plugin *plugin); TALER_EXCHANGEDB_plugin_unload (struct TALER_EXCHANGEDB_Plugin *plugin);
/** /**
* Information about an account from the configuration. * Information about an account from the configuration.
*/ */

View File

@ -19,15 +19,42 @@
* @author Sree Harsha Totakura <sreeharsha@totakura.in> * @author Sree Harsha Totakura <sreeharsha@totakura.in>
* @author Florian Dold * @author Florian Dold
* @author Christian Grothoff * @author Christian Grothoff
* @author Özgür Kesim
*/ */
#ifndef TALER_PQ_LIB_H_ #ifndef TALER_PQ_LIB_H_
#define TALER_PQ_LIB_H_ #define TALER_PQ_LIB_H_
#include <libpq-fe.h> #include <libpq-fe.h>
#include <jansson.h> #include <jansson.h>
#include <gnunet/gnunet_common.h>
#include <gnunet/gnunet_pq_lib.h> #include <gnunet/gnunet_pq_lib.h>
#include "taler_util.h" #include "taler_util.h"
/**
* Enumerates the composite types that Taler defines in Postgres.
* The corresponding OIDs (which are assigned by postgres at time of
* declaration) are stored in TALER_PQ_CompositeOIDs.
*/
enum TALER_PQ_CompositeType
{
TALER_PQ_CompositeAmount,
TALER_PQ_CompositeMAX /* MUST be last */
};
/**
* The correspondence of the Composite types and their OID in Postgres
*/
extern Oid TALER_PQ_CompositeOIDs[TALER_PQ_CompositeMAX];
/**
* Initialize the list of OIDs in TALER_PQ_CompositeOIDs. MUST be called
* before any composite type is used in arrays-specs/-params.
*
* @return GNUNET_SYSERR on failure
*/
enum GNUNET_GenericReturnValue
TALER_PQ_load_oids_for_composite_types (struct GNUNET_PQ_Context *db);
/** /**
* Generate query parameter for a currency, consisting of the three * Generate query parameter for a currency, consisting of the three
* components "value", "fraction" and "currency" in this order. The * components "value", "fraction" and "currency" in this order. The

View File

@ -10,6 +10,8 @@ lib_LTLIBRARIES = \
libtalerpq.la libtalerpq.la
libtalerpq_la_SOURCES = \ libtalerpq_la_SOURCES = \
pq_common.h \
pq_composite_types.c \
pq_query_helper.c \ pq_query_helper.c \
pq_result_helper.c pq_result_helper.c
libtalerpq_la_LIBADD = \ libtalerpq_la_LIBADD = \

View File

@ -47,20 +47,6 @@ enum TALER_PQ_ArrayType
TALER_PQ_array_of_MAX, /* must be last */ TALER_PQ_array_of_MAX, /* must be last */
}; };
/**
* The header for a postgresql array in binary format. note that this a
* simplified special case of the general structure (which contains pointers),
* as we only support one-dimensional arrays.
*/
struct TALER_PQ_ArrayHeader_P
{
uint32_t ndim; /* number of dimensions. we only support ndim = 1 */
uint32_t has_null;
uint32_t oid;
uint32_t dim; /* size of the array */
uint32_t lbound; /* index value of first element in the db (default: 1). */
} __attribute__((packed));
/** /**
* Memory representation of an taler amount record for Postgres. * Memory representation of an taler amount record for Postgres.
* *
@ -92,5 +78,6 @@ struct TALER_PQ_Amount_P
.f = htonl ((amount)->fraction) \ .f = htonl ((amount)->fraction) \
} }
#endif /* TALER_PQ_COMMON_H_ */ #endif /* TALER_PQ_COMMON_H_ */
/* end of pg/pq_common.h */ /* end of pg/pq_common.h */

View File

@ -0,0 +1,57 @@
/*
This file is part of TALER
Copyright (C) 2023 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 pq/pq_composite_types.c
* @brief helper functions for Taler-specific libpq (PostGres) interactions with composite types
* @author Özgür Kesim
*/
#include "platform.h"
#include <gnunet/gnunet_common.h>
#include <gnunet/gnunet_util_lib.h>
#include <gnunet/gnunet_pq_lib.h>
#include "taler_pq_lib.h"
#include "pq_common.h"
Oid TALER_PQ_CompositeOIDs[TALER_PQ_CompositeMAX] = {0};
enum GNUNET_GenericReturnValue
TALER_PQ_load_oids_for_composite_types (
struct GNUNET_PQ_Context *db)
{
static char *names[] = {
[TALER_PQ_CompositeAmount] = "taler_amount"
};
size_t num = sizeof(names) / sizeof(names[0]);
GNUNET_static_assert (num == TALER_PQ_CompositeMAX);
for (size_t i = 0; i < num; i++)
{
enum GNUNET_GenericReturnValue ret;
enum TALER_PQ_CompositeType typ = i;
ret = GNUNET_PQ_get_oid_by_name (db,
names[i],
&TALER_PQ_CompositeOIDs[typ]);
if (GNUNET_OK != ret)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to load OID for type %s\n",
names[i]);
return GNUNET_SYSERR;
}
}
return GNUNET_OK;
}

View File

@ -872,7 +872,7 @@ qconv_array (
RETURN_UNLESS ((0 == num) || (y / num == x)); RETURN_UNLESS ((0 == num) || (y / num == x));
/* size of header */ /* size of header */
total_size = x = sizeof(struct TALER_PQ_ArrayHeader_P); total_size = x = sizeof(struct GNUNET_PQ_ArrayHeader_P);
total_size += y; total_size += y;
RETURN_UNLESS (total_size >= x); RETURN_UNLESS (total_size >= x);
@ -941,7 +941,7 @@ qconv_array (
/* Write data */ /* Write data */
{ {
char *out = elements; char *out = elements;
struct TALER_PQ_ArrayHeader_P h = { struct GNUNET_PQ_ArrayHeader_P h = {
.ndim = htonl (1), /* We only support one-dimensional arrays */ .ndim = htonl (1), /* We only support one-dimensional arrays */
.has_null = htonl (0), /* We do not support NULL entries in arrays */ .has_null = htonl (0), /* We do not support NULL entries in arrays */
.lbound = htonl (1), /* Default start index value */ .lbound = htonl (1), /* Default start index value */

View File

@ -1166,7 +1166,7 @@ extract_array_generic (
int data_sz; int data_sz;
char *data; char *data;
void *out = NULL; void *out = NULL;
struct TALER_PQ_ArrayHeader_P header; struct GNUNET_PQ_ArrayHeader_P header;
int col_num; int col_num;
GNUNET_assert (NULL != dst); GNUNET_assert (NULL != dst);
@ -1192,8 +1192,8 @@ extract_array_generic (
FAIL_IF (NULL == data); FAIL_IF (NULL == data);
{ {
struct TALER_PQ_ArrayHeader_P *h = struct GNUNET_PQ_ArrayHeader_P *h =
(struct TALER_PQ_ArrayHeader_P *) data; (struct GNUNET_PQ_ArrayHeader_P *) data;
header.ndim = ntohl (h->ndim); header.ndim = ntohl (h->ndim);
header.has_null = ntohl (h->has_null); header.has_null = ntohl (h->has_null);

View File

@ -194,6 +194,16 @@ main (int argc,
GNUNET_PQ_disconnect (conn); GNUNET_PQ_disconnect (conn);
return 1; return 1;
} }
ret = TALER_PQ_load_oids_for_composite_types (conn);
if (GNUNET_OK != ret)
{
fprintf (stderr,
"Failed to load oids for composites\n");
GNUNET_PQ_disconnect (conn);
return 1;
}
ret = run_queries (conn); ret = run_queries (conn);
{ {
struct GNUNET_PQ_ExecuteStatement ds[] = { struct GNUNET_PQ_ExecuteStatement ds[] = {