make earning more tangible
This commit is contained in:
parent
9581160944
commit
7aa6a02a08
|
@ -1,25 +0,0 @@
|
||||||
// https://en.wikipedia.org/wiki/Normal_distribution#Quantile_function
|
|
||||||
// const z = 1.281551565545 // 80% confidence
|
|
||||||
// const z = 1.644853626951 // 90% confidence
|
|
||||||
// const z = 1.959963984540 // 95% confidence
|
|
||||||
const z = 3.090232306168 // 98% confidence
|
|
||||||
|
|
||||||
function confidence (s, n) {
|
|
||||||
if (n === 0) {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
const p = s / n
|
|
||||||
const left = p + 1 / (2 * n) * z * z
|
|
||||||
const right = z * Math.sqrt(p * (1 - p) / n + z * z / (4 * n * n))
|
|
||||||
const under = 1 + 1 / n * z * z
|
|
||||||
|
|
||||||
return (left - right) / under
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(confidence(process.argv[2], process.argv[3]))
|
|
||||||
|
|
||||||
/*
|
|
||||||
Need to describe how they'll earn
|
|
||||||
If we trust upvotes how can we use that to determine the best
|
|
||||||
*/
|
|
113
worker/earn.js
113
worker/earn.js
|
@ -1,5 +1,10 @@
|
||||||
const serialize = require('../api/resolvers/serial')
|
const serialize = require('../api/resolvers/serial')
|
||||||
|
|
||||||
|
const ITEM_EACH_REWARD = 3.0
|
||||||
|
const UPVOTE_EACH_REWARD = 6.0
|
||||||
|
const TOP_ITEMS = 21
|
||||||
|
const EARLY_MULTIPLIER_MAX = 100.0
|
||||||
|
|
||||||
// TODO: use a weekly trust measure or make trust decay
|
// TODO: use a weekly trust measure or make trust decay
|
||||||
function earn ({ models }) {
|
function earn ({ models }) {
|
||||||
return async function ({ name }) {
|
return async function ({ name }) {
|
||||||
|
@ -14,18 +19,63 @@ function earn ({ models }) {
|
||||||
OR ("ItemAct".act = 'VOTE' AND "Item"."userId" = "ItemAct"."userId"))
|
OR ("ItemAct".act = 'VOTE' AND "Item"."userId" = "ItemAct"."userId"))
|
||||||
AND "ItemAct".created_at > now_utc() - INTERVAL '1 day'`
|
AND "ItemAct".created_at > now_utc() - INTERVAL '1 day'`
|
||||||
|
|
||||||
// calculate the total trust
|
/*
|
||||||
const { sum: { trust } } = await models.user.aggregate({
|
How earnings work:
|
||||||
sum: {
|
1/3: top 21 posts over last 36 hours, scored on a relative basis
|
||||||
trust: true
|
1/3: top 21 comments over last 36 hours, scored on a relative basis
|
||||||
}
|
1/3: top upvoters of top posts/comments, scored on:
|
||||||
})
|
- their trust
|
||||||
|
- how much they tipped
|
||||||
|
- how early they upvoted it
|
||||||
|
- how the post/comment scored
|
||||||
|
*/
|
||||||
|
|
||||||
// get earners { id, earnings }
|
// get earners { id, earnings }
|
||||||
const earners = await models.$queryRaw(`
|
const earners = await models.$queryRaw(`
|
||||||
SELECT id, FLOOR(${sum} * (trust/${trust}) * 1000) as earnings
|
WITH item_ratios AS (
|
||||||
FROM users
|
SELECT *,
|
||||||
WHERE trust > 0`)
|
"weightedVotes"/(sum("weightedVotes") OVER (PARTITION BY "parentId" IS NULL)) AS ratio
|
||||||
|
FROM (
|
||||||
|
SELECT *,
|
||||||
|
ROW_NUMBER() OVER (PARTITION BY "parentId" IS NULL ORDER BY "weightedVotes" desc) AS r
|
||||||
|
FROM
|
||||||
|
"Item"
|
||||||
|
WHERE created_at >= now_utc() - interval '36 hours'
|
||||||
|
) x
|
||||||
|
WHERE x.r <= ${TOP_ITEMS}
|
||||||
|
),
|
||||||
|
upvoters AS (
|
||||||
|
SELECT "ItemAct"."userId", item_ratios.id, item_ratios.ratio, item_ratios."parentId",
|
||||||
|
sum("ItemAct".sats) as tipped, min("ItemAct".created_at) as acted_at
|
||||||
|
FROM item_ratios
|
||||||
|
JOIN "ItemAct" on "ItemAct"."itemId" = item_ratios.id
|
||||||
|
WHERE act IN ('VOTE','TIP')
|
||||||
|
AND "ItemAct"."userId" <> item_ratios."userId"
|
||||||
|
GROUP BY "ItemAct"."userId", item_ratios.id, item_ratios.ratio, item_ratios."parentId"
|
||||||
|
),
|
||||||
|
upvoter_ratios AS (
|
||||||
|
SELECT "userId", sum(early_multiplier*tipped_ratio*ratio*users.trust) as upvoting_score,
|
||||||
|
"parentId" IS NULL as "isPost"
|
||||||
|
FROM (
|
||||||
|
SELECT *,
|
||||||
|
${EARLY_MULTIPLIER_MAX}/(ROW_NUMBER() OVER (partition by id order by acted_at asc)) AS early_multiplier,
|
||||||
|
tipped::float/(sum(tipped) OVER (partition by id)) tipped_ratio
|
||||||
|
FROM upvoters
|
||||||
|
) u
|
||||||
|
JOIN users on "userId" = users.id
|
||||||
|
GROUP BY "userId", "parentId" IS NULL
|
||||||
|
)
|
||||||
|
SELECT "userId" as id, FLOOR(sum(proportion)*${sum}*1000) as earnings
|
||||||
|
FROM (
|
||||||
|
SELECT "userId",
|
||||||
|
upvoting_score/(sum(upvoting_score) OVER (PARTITION BY "isPost"))/${UPVOTE_EACH_REWARD} as proportion
|
||||||
|
FROM upvoter_ratios
|
||||||
|
UNION ALL
|
||||||
|
SELECT "userId", ratio/${ITEM_EACH_REWARD} as proportion
|
||||||
|
FROM item_ratios
|
||||||
|
) a
|
||||||
|
GROUP BY "userId"
|
||||||
|
HAVING FLOOR(sum(proportion)*${sum}) >= 1`)
|
||||||
|
|
||||||
// for each earner, serialize earnings
|
// for each earner, serialize earnings
|
||||||
// we do this for each earner because we don't need to serialize
|
// we do this for each earner because we don't need to serialize
|
||||||
|
@ -41,47 +91,4 @@ function earn ({ models }) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// earn historical ... TODO: delete after announcement
|
module.exports = { earn }
|
||||||
function earnHistorical ({ models }) {
|
|
||||||
return async function ({ name }) {
|
|
||||||
console.log('running', name)
|
|
||||||
|
|
||||||
// compute how much sn earned today
|
|
||||||
const [{ sum }] = await models.$queryRaw`
|
|
||||||
SELECT sum("ItemAct".sats)
|
|
||||||
FROM "ItemAct"
|
|
||||||
JOIN "Item" on "ItemAct"."itemId" = "Item".id
|
|
||||||
WHERE ("ItemAct".act in ('BOOST', 'STREAM')
|
|
||||||
OR ("ItemAct".act = 'VOTE' AND "Item"."userId" = "ItemAct"."userId"))`
|
|
||||||
|
|
||||||
// add in the job sats that weren't recorded from jobs
|
|
||||||
const fullSum = 200000 + sum
|
|
||||||
|
|
||||||
// calculate the total trust
|
|
||||||
const { sum: { trust } } = await models.user.aggregate({
|
|
||||||
sum: {
|
|
||||||
trust: true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// get earners { id, earnings }
|
|
||||||
const earners = await models.$queryRaw(`
|
|
||||||
SELECT id, FLOOR(${fullSum} * (trust/${trust}) * 1000) as earnings
|
|
||||||
FROM users
|
|
||||||
WHERE trust > 0`)
|
|
||||||
|
|
||||||
// for each earner, serialize earnings
|
|
||||||
// we do this for each earner because we don't need to serialize
|
|
||||||
// all earner updates together
|
|
||||||
earners.forEach(async earner => {
|
|
||||||
if (earner.earnings > 0) {
|
|
||||||
await serialize(models,
|
|
||||||
models.$executeRaw`SELECT earn(${earner.id}, ${earner.earnings})`)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
console.log('done', name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { earn, earnHistorical }
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ const { checkInvoice, checkWithdrawal } = require('./wallet')
|
||||||
const { repin } = require('./repin')
|
const { repin } = require('./repin')
|
||||||
const { trust } = require('./trust')
|
const { trust } = require('./trust')
|
||||||
const { auction } = require('./auction')
|
const { auction } = require('./auction')
|
||||||
const { earn, earnHistorical } = require('./earn')
|
const { earn } = require('./earn')
|
||||||
const { ApolloClient, HttpLink, InMemoryCache } = require('@apollo/client')
|
const { ApolloClient, HttpLink, InMemoryCache } = require('@apollo/client')
|
||||||
const { indexItem, indexAllItems } = require('./search')
|
const { indexItem, indexAllItems } = require('./search')
|
||||||
const fetch = require('cross-fetch')
|
const fetch = require('cross-fetch')
|
||||||
|
@ -45,7 +45,6 @@ async function work () {
|
||||||
await boss.work('indexAllItems', indexAllItems(args))
|
await boss.work('indexAllItems', indexAllItems(args))
|
||||||
await boss.work('auction', auction(args))
|
await boss.work('auction', auction(args))
|
||||||
await boss.work('earn', earn(args))
|
await boss.work('earn', earn(args))
|
||||||
await boss.work('earnHistorical', earnHistorical(args))
|
|
||||||
|
|
||||||
console.log('working jobs')
|
console.log('working jobs')
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue