115 lines
4.5 KiB
PL/PgSQL
115 lines
4.5 KiB
PL/PgSQL
DROP FUNCTION weighted_downvotes_after_act(item_id INTEGER, user_id INTEGER, sats INTEGER);
|
|
CREATE OR REPLACE FUNCTION weighted_downvotes_after_act(item_id INTEGER, user_id INTEGER, sats INTEGER) RETURNS INTEGER AS $$
|
|
DECLARE
|
|
user_trust DOUBLE PRECISION;
|
|
sats_past INTEGER;
|
|
multiplier DOUBLE PRECISION;
|
|
BEGIN
|
|
-- grab user's trust who is upvoting
|
|
SELECT trust INTO user_trust FROM users WHERE id = user_id;
|
|
|
|
-- in order to add this to weightedVotes, we need to do log((satsN+satsPrior)/satsPrior)
|
|
-- so compute sats prior
|
|
SELECT SUM(msats) / 1000 INTO sats_past
|
|
FROM "ItemAct"
|
|
WHERE "userId" = user_id AND "itemId" = item_id AND act IN ('DONT_LIKE_THIS');
|
|
|
|
IF sats_past IS NULL OR sats_past = 0 THEN
|
|
multiplier := LOG(sats);
|
|
ELSE
|
|
multiplier := LOG((sats+sats_past)/sats_past::FLOAT);
|
|
END IF;
|
|
|
|
-- update item
|
|
UPDATE "Item"
|
|
SET "weightedDownVotes" = "weightedDownVotes" + (user_trust * multiplier)
|
|
WHERE id = item_id AND "userId" <> user_id;
|
|
|
|
RETURN 0;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
-- Update item_act to support multiple dont_like_this
|
|
CREATE OR REPLACE FUNCTION item_act(item_id INTEGER, user_id INTEGER, act "ItemActType", act_sats INTEGER)
|
|
RETURNS INTEGER
|
|
LANGUAGE plpgsql
|
|
AS $$
|
|
DECLARE
|
|
user_msats BIGINT;
|
|
act_msats BIGINT;
|
|
fee_msats BIGINT;
|
|
item_act_id INTEGER;
|
|
fwd_entry record; -- for loop iterator variable to iterate across forward recipients
|
|
fwd_msats BIGINT; -- for loop variable calculating how many msats to give each forward recipient
|
|
total_fwd_msats BIGINT := 0; -- accumulator to see how many msats have been forwarded for the act
|
|
BEGIN
|
|
PERFORM ASSERT_SERIALIZED();
|
|
|
|
act_msats := act_sats * 1000;
|
|
SELECT msats INTO user_msats FROM users WHERE id = user_id;
|
|
IF act_msats > user_msats THEN
|
|
RAISE EXCEPTION 'SN_INSUFFICIENT_FUNDS';
|
|
END IF;
|
|
|
|
-- deduct msats from actor
|
|
UPDATE users SET msats = msats - act_msats WHERE id = user_id;
|
|
|
|
IF act = 'TIP' THEN
|
|
-- call to influence weightedVotes ... we need to do this before we record the acts because
|
|
-- the priors acts are taken into account
|
|
PERFORM weighted_votes_after_tip(item_id, user_id, act_sats);
|
|
-- call to denormalize sats and commentSats
|
|
PERFORM sats_after_tip(item_id, user_id, act_msats);
|
|
|
|
-- take 10% and insert as FEE
|
|
fee_msats := CEIL(act_msats * 0.1);
|
|
act_msats := act_msats - fee_msats;
|
|
|
|
-- save the fee act into item_act_id so we can record referral acts
|
|
INSERT INTO "ItemAct" (msats, "itemId", "userId", act, created_at, updated_at)
|
|
VALUES (fee_msats, item_id, user_id, 'FEE', now_utc(), now_utc())
|
|
RETURNING id INTO item_act_id;
|
|
|
|
-- leave the rest as a tip
|
|
INSERT INTO "ItemAct" (msats, "itemId", "userId", act, created_at, updated_at)
|
|
VALUES (act_msats, item_id, user_id, 'TIP', now_utc(), now_utc());
|
|
|
|
-- denormalize bounty paid (if applicable)
|
|
PERFORM bounty_paid_after_act(item_id, user_id);
|
|
|
|
-- add sats to actees' balance and stacked count
|
|
FOR fwd_entry IN SELECT "userId", "pct" FROM "ItemForward" WHERE "itemId" = item_id
|
|
LOOP
|
|
-- fwd_msats represents the sats for this forward recipient from this particular tip action
|
|
fwd_msats := act_msats * fwd_entry.pct / 100;
|
|
-- keep track of how many msats have been forwarded, so we can give any remaining to OP
|
|
total_fwd_msats := fwd_msats + total_fwd_msats;
|
|
|
|
UPDATE users
|
|
SET msats = msats + fwd_msats, "stackedMsats" = "stackedMsats" + fwd_msats
|
|
WHERE id = fwd_entry."userId";
|
|
END LOOP;
|
|
|
|
-- Give OP any remaining msats after forwards have been applied
|
|
IF act_msats - total_fwd_msats > 0 THEN
|
|
UPDATE users
|
|
SET msats = msats + act_msats - total_fwd_msats, "stackedMsats" = "stackedMsats" + act_msats - total_fwd_msats
|
|
WHERE id = (SELECT "userId" FROM "Item" WHERE id = item_id);
|
|
END IF;
|
|
ELSE -- BOOST, POLL, DONT_LIKE_THIS, STREAM
|
|
-- call to influence if DONT_LIKE_THIS weightedDownVotes
|
|
IF act = 'DONT_LIKE_THIS' THEN
|
|
PERFORM weighted_downvotes_after_act(item_id, user_id, act_sats);
|
|
END IF;
|
|
|
|
INSERT INTO "ItemAct" (msats, "itemId", "userId", act, created_at, updated_at)
|
|
VALUES (act_msats, item_id, user_id, act, now_utc(), now_utc())
|
|
RETURNING id INTO item_act_id;
|
|
END IF;
|
|
|
|
-- store referral effects
|
|
PERFORM referral_act(item_act_id);
|
|
|
|
RETURN 0;
|
|
END;
|
|
$$; |