fix auction to work as described

This commit is contained in:
keyan 2022-03-02 14:55:13 -06:00
parent cd3125954e
commit 87e4376c10
2 changed files with 64 additions and 5 deletions

View File

@ -0,0 +1,36 @@
-- take a bid and return whether they have enough funds to support it
CREATE OR REPLACE FUNCTION run_auction(item_id INTEGER, bid INTEGER) RETURNS BOOLEAN AS $$
DECLARE
bpm_msats INTEGER;
user_id INTEGER;
user_msats INTEGER;
item_status "Status";
BEGIN
PERFORM ASSERT_SERIALIZED();
bpm_msats := (bid * 5) / 216;
-- extract data we need
SELECT "userId", status INTO user_id, item_status FROM "Item" WHERE id = item_id;
SELECT msats INTO user_msats FROM users WHERE id = user_id;
-- check if user wallet has enough sats
IF bpm_msats > user_msats THEN
-- if not, set status = NOSATS and statusUpdatedAt to now_utc if not already set
IF item_status <> 'NOSATS' THEN
UPDATE "Item" SET status = 'NOSATS', "statusUpdatedAt" = now_utc() WHERE id = item_id;
END IF;
RETURN false;
ELSE
-- if so, deduct from user
UPDATE users SET msats = msats - bpm_msats WHERE id = user_id;
-- update item status = ACTIVE and statusUpdatedAt = null if NOSATS
IF item_status = 'NOSATS' THEN
UPDATE "Item" SET status = 'ACTIVE', "statusUpdatedAt" = now_utc() WHERE id = item_id;
END IF;
RETURN true;
END IF;
END;
$$ LANGUAGE plpgsql;

View File

@ -3,7 +3,12 @@ const serialize = require('../api/resolvers/serial')
function auction ({ models }) {
return async function ({ name }) {
console.log('running', name)
// get all items we need to check
// TODO: do this for each sub with auction ranking
// because we only have one auction sub, we don't need to do this
const SUB_BASE_COST = 10000
const BID_DELTA = 1000
// get all items we need to check in order of low to high bid
const items = await models.item.findMany(
{
where: {
@ -13,15 +18,33 @@ function auction ({ models }) {
status: {
not: 'STOPPED'
}
},
orderBy: {
maxBid: 'asc'
}
}
)
// we subtract bid delta so that the lowest bidder, pays
// the sub base cost
let lastBid = SUB_BASE_COST - BID_DELTA
// for each item, run serialized auction function
items.forEach(async item => {
await serialize(models,
models.$executeRaw`SELECT run_auction(${item.id})`)
})
for (const item of items) {
let bid = lastBid
// if this item's maxBid is great enough, have them pay more
// else have them match the last bid
if (item.maxBid >= lastBid + BID_DELTA) {
bid = lastBid + BID_DELTA
}
const [{ run_auction: succeeded }] = await serialize(models,
models.$queryRaw`SELECT run_auction(${item.id}, ${bid})`)
// if we succeeded update the lastBid
if (succeeded) {
lastBid = bid
}
}
console.log('done', name)
}