april million sat madness

This commit is contained in:
keyan 2024-03-31 16:53:57 -05:00
parent 6cc4f29382
commit 2c9e668177
7 changed files with 126 additions and 75 deletions

View File

@ -161,7 +161,7 @@ export default {
const [{ to, from }] = await models.$queryRaw` const [{ to, from }] = await models.$queryRaw`
SELECT date_trunc('month', (now() AT TIME ZONE 'America/Chicago')) AT TIME ZONE 'America/Chicago' as from, SELECT date_trunc('month', (now() AT TIME ZONE 'America/Chicago')) AT TIME ZONE 'America/Chicago' as from,
(date_trunc('month', (now() AT TIME ZONE 'America/Chicago')) AT TIME ZONE 'America/Chicago') + interval '1 month - 1 second' as to` (date_trunc('month', (now() AT TIME ZONE 'America/Chicago')) AT TIME ZONE 'America/Chicago') + interval '1 month - 1 second' as to`
return await topUsers(parent, { when: 'custom', to: new Date(to).getTime().toString(), from: new Date(from).getTime().toString(), limit: 64 }, { models, ...context }) return await topUsers(parent, { when: 'custom', to: new Date(to).getTime().toString(), from: new Date(from).getTime().toString(), limit: 100 }, { models, ...context })
} }
}, },
Mutation: { Mutation: {

View File

@ -5,7 +5,7 @@ import { decodeCursor, LIMIT, nextCursorEncoded } from '@/lib/cursor'
import { msatsToSats } from '@/lib/format' import { msatsToSats } from '@/lib/format'
import { bioSchema, emailSchema, settingsSchema, ssValidate, userSchema } from '@/lib/validate' import { bioSchema, emailSchema, settingsSchema, ssValidate, userSchema } from '@/lib/validate'
import { getItem, updateItem, filterClause, createItem, whereClause, muteClause } from './item' import { getItem, updateItem, filterClause, createItem, whereClause, muteClause } from './item'
import { ANON_USER_ID, DELETE_USER_ID, RESERVED_MAX_USER_ID, SN_USER_IDS } from '@/lib/constants' import { ANON_USER_ID, DELETE_USER_ID, RESERVED_MAX_USER_ID, SN_NO_REWARDS_IDS } from '@/lib/constants'
import { viewGroup } from './growth' import { viewGroup } from './growth'
import { whenRange } from '@/lib/time' import { whenRange } from '@/lib/time'
@ -106,7 +106,7 @@ export function viewValueGroup () {
WHERE user_values_today.t >= date_trunc('day', timezone('America/Chicago', $1)) WHERE user_values_today.t >= date_trunc('day', timezone('America/Chicago', $1))
AND date_trunc('day', user_values_today.t) <= date_trunc('day', timezone('America/Chicago', $2))) AND date_trunc('day', user_values_today.t) <= date_trunc('day', timezone('America/Chicago', $2)))
) v ) v
WHERE v.id NOT IN (${SN_USER_IDS.join(',')}) WHERE v.id NOT IN (${SN_NO_REWARDS_IDS.join(',')})
GROUP BY v.id GROUP BY v.id
) vv` ) vv`
} }

View File

@ -37,6 +37,7 @@ export const ANON_ITEM_SPAM_INTERVAL = '0'
export const INV_PENDING_LIMIT = 100 export const INV_PENDING_LIMIT = 100
export const BALANCE_LIMIT_MSATS = 250000000 // 250k sat export const BALANCE_LIMIT_MSATS = 250000000 // 250k sat
export const SN_USER_IDS = [616, 6030, 946, 4502, 27] export const SN_USER_IDS = [616, 6030, 946, 4502, 27]
export const SN_NO_REWARDS_IDS = [27, 4502]
export const ANON_INV_PENDING_LIMIT = 1000 export const ANON_INV_PENDING_LIMIT = 1000
export const ANON_BALANCE_LIMIT_MSATS = 0 // disable export const ANON_BALANCE_LIMIT_MSATS = 0 // disable
export const MAX_POLL_NUM_CHOICES = 10 export const MAX_POLL_NUM_CHOICES = 10

View File

@ -1,66 +1,101 @@
export const proportions = [ export const proportions = [
0.3312903760145768, 0.08122,
0.09938711280437303, 0.07,
0.06625807520291535, 0.06,
0.04969355640218651, 0.05,
0.033129037601457675, 0.045,
0.02981613384131191, 0.04,
0.026503230081166142, 0.035,
0.023190326321020374, 0.03,
0.019877422560874606, 0.029,
0.016564518800728838, 0.028,
0.014908066920655955, 0.027,
0.013251615040583071, 0.026,
0.012920324664568494, 0.025,
0.012589034288553918, 0.024,
0.01225774391253934, 0.023,
0.011926453536524764, 0.022,
0.011595163160510187, 0.021,
0.01126387278449561, 0.02,
0.010932582408481033, 0.019,
0.010601292032466457, 0.018,
0.01027000165645188, 0.017,
0.009938711280437303, 0.016,
0.009607420904422726, 0.015,
0.00927613052840815, 0.014,
0.008944840152393572, 0.013,
0.008613549776378996, 0.012,
0.008282259400364419, 0.011,
0.007950969024349842, 0.01,
0.007619678648335266, 0.009,
0.007288388272320689, 0.0083,
0.006957097896306112, 0.0077,
0.006625807520291536, 0.0074,
0.006294517144276959, 0.0071,
0.005963226768262382, 0.0068,
0.005631936392247805, 0.0065,
0.005300646016233228, 0.0063,
0.0049693556402186515, 0.0061,
0.004638065264204075, 0.0059,
0.004306774888189498, 0.0057,
0.003975484512174921, 0.0055,
0.0036441941361603446, 0.0053,
0.003312903760145768, 0.0051,
0.0031472585721384794, 0.0049,
0.002981613384131191, 0.0047,
0.0028159681961239026, 0.0045,
0.002650323008116614, 0.0043,
0.0024846778201093257, 0.0041,
0.0023190326321020373, 0.0039,
0.002153387444094749, 0.0037,
0.0019877422560874605, 0.0036,
0.0018220970680801723, 0.0035,
0.001656451880072884, 0.0034,
0.0014908066920655955, 0.0033,
0.001325161504058307, 0.0032,
0.0011595163160510187, 0.0031,
0.0009938711280437303, 0.003,
0.000828225940036442, 0.0029,
0.0006625807520291535, 0.0028,
0.0004969355640218651, 0.0027,
0.00033129037601457677, 0.0026,
0.00033129037601457677, 0.0025,
0.00033129037601457677, 0.0024,
0.00033129037601457677, 0.0023,
0.00033129037601457677 0.0022,
0.0021,
0.002,
0.0019,
0.0018,
0.0017,
0.0016,
0.0015,
0.0014,
0.0013,
0.0012,
0.0011,
0.001,
0.0009,
0.0008,
0.00078,
0.00076,
0.00074,
0.00072,
0.0007,
0.00068,
0.00066,
0.00064,
0.00062,
0.0006,
0.00058,
0.00056,
0.00054,
0.00052,
0.0005,
0.00048,
0.00046,
0.00044,
0.00042,
0.0004,
0.00038
] ]

View File

@ -99,7 +99,7 @@ export default function Rewards ({ ssrData }) {
let { rewards: [{ total, sources, time, leaderboard }] } = useData(data, ssrData) let { rewards: [{ total, sources, time, leaderboard }] } = useData(data, ssrData)
if (rewardsData?.rewards?.length > 0) { if (rewardsData?.rewards?.length > 0) {
total = rewardsData.rewards[0].total total = rewardsData.rewards[0].total - 1000000 > 0 ? rewardsData.rewards[0].total - 1000000 : 0
sources = rewardsData.rewards[0].sources sources = rewardsData.rewards[0].sources
time = rewardsData.rewards[0].time time = rewardsData.rewards[0].time
} }
@ -108,7 +108,7 @@ export default function Rewards ({ ssrData }) {
return ( return (
<div className='text-muted fst-italic'> <div className='text-muted fst-italic'>
<small> <small>
<span>estimated reward: {numWithUnits(Math.floor(total * proportions[rank - 1]))}</span> <span>estimated reward: {numWithUnits(rank === 1 ? 1000000 : Math.floor(total * proportions[rank - 2]))}</span>
</small> </small>
</div> </div>
) )
@ -116,12 +116,18 @@ export default function Rewards ({ ssrData }) {
return ( return (
<Layout footerLinks> <Layout footerLinks>
<Row className='py-3'> <h3 className='pt-3 text-center' style={{ lineHeight: 1.5 }}>
Rewards are sponsored by{' '}
<Link href='https://btcplusplus.dev/conf/atx24' target='_blank' rel='noreferrer'>
the Austin Bitcoin++ Conference May 1-4
</Link>
</h3>
<Row className='pb-3'>
<Col> <Col>
<div <div
className='d-flex flex-column sticky-lg-top py-5' className='d-flex flex-column sticky-lg-top py-5'
> >
<h3 className='text-center'> <h3 className='text-center text-muted'>
<div> <div>
<RewardLine total={total} time={time} /> <RewardLine total={total} time={time} />
</div> </div>
@ -137,7 +143,7 @@ export default function Rewards ({ ssrData }) {
</Col> </Col>
{leaderboard?.users && {leaderboard?.users &&
<Col lg={7}> <Col lg={7}>
<h2 className='pt-5 text-center'>leaderboard</h2> <h2 className='pt-5 text-center text-muted'>leaderboard</h2>
<div className='d-flex justify-content-center pt-4'> <div className='d-flex justify-content-center pt-4'>
<ListUsers users={leaderboard.users} rank Embellish={EstimatedReward} /> <ListUsers users={leaderboard.users} rank Embellish={EstimatedReward} />
</div> </div>

View File

@ -7,6 +7,7 @@ import Snl from '@/components/snl'
import { useQuery } from '@apollo/client' import { useQuery } from '@apollo/client'
import PageLoading from '@/components/page-loading' import PageLoading from '@/components/page-loading'
import TerritoryHeader from '@/components/territory-header' import TerritoryHeader from '@/components/territory-header'
import Link from 'next/link'
export const getServerSideProps = getGetServerSideProps({ export const getServerSideProps = getGetServerSideProps({
query: SUB_ITEMS, query: SUB_ITEMS,
@ -29,6 +30,14 @@ export default function Sub ({ ssrData }) {
<> <>
<Snl /> <Snl />
</>)} </>)}
<small className='pb-3 px-1 text-muted' style={{ marginTop: '-0.25rem', lineHeight: 1.5 }}>
<Link className='text-reset' href='/rewards' style={{ textDecoration: 'underline' }}>
Million Sat Madness
</Link> is sponsored by{' '}
<Link className='text-reset' href='https://btcplusplus.dev/conf/atx24' target='_blank' rel='noreferrer' style={{ textDecoration: 'underline' }}>
the Austin Bitcoin++ Conference May 1-4
</Link>
</small>
<Items ssrData={ssrData} variables={variables} /> <Items ssrData={ssrData} variables={variables} />
</Layout> </Layout>
) )

View File

@ -2,7 +2,7 @@ import serialize from '@/api/resolvers/serial.js'
import { notifyEarner } from '@/lib/webPush.js' import { notifyEarner } from '@/lib/webPush.js'
import { PrismaClient } from '@prisma/client' import { PrismaClient } from '@prisma/client'
import { proportions } from '@/lib/madness.js' import { proportions } from '@/lib/madness.js'
import { SN_USER_IDS } from '@/lib/constants.js' import { SN_NO_REWARDS_IDS } from '@/lib/constants.js'
const TOTAL_UPPER_BOUND_MSATS = 10000000000 const TOTAL_UPPER_BOUND_MSATS = 10000000000
@ -55,10 +55,10 @@ export async function earn ({ name }) {
SELECT id AS "userId", sum(proportion) as proportion, ROW_NUMBER() OVER (ORDER BY sum(proportion) DESC) as rank SELECT id AS "userId", sum(proportion) as proportion, ROW_NUMBER() OVER (ORDER BY sum(proportion) DESC) as rank
FROM user_values_days FROM user_values_days
WHERE date_trunc('month', user_values_days.t) = date_trunc('month', (now() - interval '1 month') AT TIME ZONE 'America/Chicago') WHERE date_trunc('month', user_values_days.t) = date_trunc('month', (now() - interval '1 month') AT TIME ZONE 'America/Chicago')
AND NOT (id = ANY (${SN_USER_IDS})) AND NOT (id = ANY (${SN_NO_REWARDS_IDS}))
GROUP BY id GROUP BY id
ORDER BY proportion DESC ORDER BY proportion DESC
LIMIT 64` LIMIT 100`
// in order to group earnings for users we use the same createdAt time for // in order to group earnings for users we use the same createdAt time for
// all earnings // all earnings