aboutsummaryrefslogtreecommitdiff
path: root/src/exchangedb/procedures.sql
diff options
context:
space:
mode:
Diffstat (limited to 'src/exchangedb/procedures.sql')
-rw-r--r--src/exchangedb/procedures.sql156
1 files changed, 155 insertions, 1 deletions
diff --git a/src/exchangedb/procedures.sql b/src/exchangedb/procedures.sql
index 1e9b6b166..90fb7d321 100644
--- a/src/exchangedb/procedures.sql
+++ b/src/exchangedb/procedures.sql
@@ -2183,8 +2183,10 @@ CREATE OR REPLACE FUNCTION exchange_do_reserve_open(
IN in_reserve_payment_val INT8,
IN in_reserve_payment_frac INT4,
IN in_min_purse_limit INT4,
+ IN in_default_purse_limit INT4,
IN in_reserve_sig BYTEA,
IN in_desired_expiration INT8,
+ IN in_reserve_gc_delay INT8,
IN in_now INT8,
IN in_open_fee_val INT8,
IN in_open_fee_frac INT4,
@@ -2194,9 +2196,161 @@ CREATE OR REPLACE FUNCTION exchange_do_reserve_open(
OUT out_no_funds BOOLEAN)
LANGUAGE plpgsql
AS $$
+DECLARE
+ my_balance_val INT8;
+DECLARE
+ my_balance_frac INT4;
+DECLARE
+ my_cost_val INT8;
+DECLARE
+ my_cost_tmp INT8;
+DECLARE
+ my_cost_frac INT4;
+DECLARE
+ my_years_tmp INT4;
+DECLARE
+ my_years INT4;
+DECLARE
+ my_needs_update BOOL;
+DECLARE
+ my_purses_allowed INT8;
+DECLARE
+ my_expiration_date INT8;
+DECLARE
+ my_reserve_expiration INT8;
BEGIN
--- FIXME: implement!
+-- FIXME: use SELECT FOR UPDATE?
+SELECT
+ purses_allowed
+ ,expiration_date
+ ,current_balance_val
+ ,current_balance_frac
+INTO
+ my_purses_allowed
+ ,my_reserve_expiration
+ ,my_balance_val
+ ,my_balance_frac
+FROM reserves
+WHERE
+ reserve_pub=in_reserve_pub;
+
+IF NOT FOUND
+THEN
+ -- FIXME: do we need to set a 'not found'?
+ RETURN;
+END IF;
+
+-- Do not allow expiration time to start in the past already
+IF (my_reserve_expiration < in_now)
+THEN
+ my_expiration_date = in_now;
+ELSE
+ my_expiration_date = my_reserve_expiration;
+END IF;
+
+my_cost_val = 0;
+my_cost_frac = 0;
+my_needs_update = FALSE;
+my_years = 0;
+
+-- Compute years based on desired expiration time
+IF (my_expiration_date < in_desired_expiration)
+THEN
+ my_years = (31535999999999 + in_desired_expiration - my_expiration_date) / 31536000000000;
+ my_purses_allowed = in_default_purse_limit;
+ my_expiration_date = my_expiration_date + 31536000000000 * my_years;
+END IF;
+
+-- Increase years based on purses requested
+IF (my_purses_allowed < in_min_purse_limit)
+THEN
+ my_years = (31535999999999 + in_desired_expiration - in_now) / 31536000000000;
+ 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 = my_years + my_years_tmp;
+ my_purses_allowed = my_purses_allowed + (in_default_purse_limit * my_years_tmp);
+END IF;
+
+-- Compute cost based on annual fees
+IF (my_years > 0)
+THEN
+ my_cost_val = my_years * in_open_fee_val;
+ my_cost_tmp = my_years * in_open_fee_frac / 100000000;
+ IF (CAST (my_cost_val + my_cost_tmp AS INT8) < my_cost_val)
+ THEN
+ out_open_cost_val=9223372036854775807;
+ out_open_cost_frac=2147483647;
+ out_final_expiration=my_expiration_date;
+ out_no_funds=true;
+ RETURN;
+ END IF;
+ my_cost_val = CAST (my_cost_val + my_cost_tmp AS INT8);
+ my_cost_frac = my_years * in_open_fee_frac % 100000000;
+ my_needs_update = TRUE;
+END IF;
+
+-- check if we actually have something to do
+IF NOT my_needs_update
+THEN
+ out_final_expiration = my_reserve_expiration;
+ out_open_cost_val = 0;
+ out_open_cost_frac = 0;
+ out_no_funds=FALSE;
+ RETURN;
+END IF;
+
+-- Check payment (coins and reserve) would be sufficient.
+IF ( (in_total_paid_val < my_cost_val) OR
+ ( (in_total_paid_val = my_cost_val) AND
+ (in_total_paid_frac < my_cost_frac) ) )
+THEN
+ out_final_expiration=my_reserve_expiration;
+ out_open_cost_val = my_cost_val;
+ out_open_cost_frac = my_cost_frac;
+ out_no_funds=TRUE;
+ RETURN;
+END IF;
+
+-- Check reserve balance is sufficient.
+IF (my_balance_val > in_reserve_payment_val)
+THEN
+ IF (my_balance_frac >= in_reserve_payment_frac)
+ THEN
+ my_balance_val=my_balance_val - in_reserve_payment_val;
+ my_balance_frac=my_balance_frac - in_reserve_payment_frac;
+ ELSE
+ my_balance_val=my_balance_val - in_reserve_payment_val - 1;
+ my_balance_frac=my_balance_frac + 100000000 - in_reserve_payment_frac;
+ END IF;
+ELSE
+ IF (my_balance_val = in_reserve_payment_val) AND (my_balance_frac >= in_reserve_payment_frac)
+ THEN
+ my_balance_val=0;
+ my_balance_frac=my_balance_frac - in_reserve_payment_frac;
+ ELSE
+ out_final_expiration=my_reserve_expiration;
+ out_open_cost_val = my_cost_val;
+ out_open_cost_frac = my_cost_frac;
+ out_no_funds=TRUE;
+ RETURN;
+ END IF;
+END IF;
+
+UPDATE reserves SET
+ current_balance_val=my_balance_val
+ ,current_balance_frac=my_balance_frac
+ ,gc_date=my_reserve_expiration + in_reserve_gc_delay
+ ,expiration_date=my_reserve_expiration
+ ,purses_allowed=my_purses_allowed
+WHERE
+ reserve_pub=in_reserve_pub;
+
+out_final_expiration=my_reserve_expiration;
+out_open_cost_val = my_cost_val;
+out_open_cost_frac = my_cost_frac;
+out_no_funds=FALSE;
+RETURN;
END $$;