Choose random hot contracts from top 16 every 5 minutes.

This commit is contained in:
jahooma 2022-01-15 00:43:15 -06:00
parent a0be5b6394
commit f6079e68d0
5 changed files with 66 additions and 11 deletions

View File

@ -1 +0,0 @@
export const randomString = () => Math.random().toString(16).substr(2, 14)

46
common/util/random.ts Normal file
View File

@ -0,0 +1,46 @@
export const randomString = () => Math.random().toString(16).substr(2, 14)
export function createRNG(seed: string) {
// https://stackoverflow.com/a/47593316/1592933
function genHash(str: string) {
// xmur3
for (var i = 0, h = 1779033703 ^ str.length; i < str.length; i++) {
h = Math.imul(h ^ str.charCodeAt(i), 3432918353)
h = (h << 13) | (h >>> 19)
}
return function () {
h = Math.imul(h ^ (h >>> 16), 2246822507)
h = Math.imul(h ^ (h >>> 13), 3266489909)
return (h ^= h >>> 16) >>> 0
}
}
const gen = genHash(seed)
let [a, b, c, d] = [gen(), gen(), gen(), gen()]
// sfc32
return function () {
a >>>= 0
b >>>= 0
c >>>= 0
d >>>= 0
var t = (a + b) | 0
a = b ^ (b >>> 9)
b = (c + (c << 3)) | 0
c = (c << 21) | (c >>> 11)
d = (d + 1) | 0
t = (t + d) | 0
c = (c + t) | 0
return (t >>> 0) / 4294967296
}
}
export const shuffle = (array: any[], rand: () => number) => {
for (let i = 0; i < array.length; i++) {
const swapIndex = Math.floor(rand() * (array.length - i))
const temp = array[i]
array[i] = array[swapIndex]
array[swapIndex] = temp
}
}

View File

@ -4,7 +4,7 @@ import * as admin from 'firebase-admin'
import { chargeUser, getUser } from './utils' import { chargeUser, getUser } from './utils'
import { Contract } from '../../common/contract' import { Contract } from '../../common/contract'
import { slugify } from '../../common/util/slugify' import { slugify } from '../../common/util/slugify'
import { randomString } from '../../common/util/random-string' import { randomString } from '../../common/util/random'
import { getNewContract } from '../../common/new-contract' import { getNewContract } from '../../common/new-contract'
import { getAnteBets, MINIMUM_ANTE } from '../../common/antes' import { getAnteBets, MINIMUM_ANTE } from '../../common/antes'

View File

@ -19,6 +19,7 @@ import { app } from './init'
import { getValues, listenForValues } from './utils' import { getValues, listenForValues } from './utils'
import { Contract } from '../../../common/contract' import { Contract } from '../../../common/contract'
import { getProbability } from '../../../common/calculate' import { getProbability } from '../../../common/calculate'
import { createRNG, shuffle } from '../../../common/util/random'
export type { Contract } export type { Contract }
export function contractPath(contract: Contract) { export function contractPath(contract: Contract) {
@ -135,15 +136,24 @@ const hotContractsQuery = query(
where('isResolved', '==', false), where('isResolved', '==', false),
where('visibility', '==', 'public'), where('visibility', '==', 'public'),
orderBy('volume24Hours', 'desc'), orderBy('volume24Hours', 'desc'),
limit(4) limit(16)
) )
function chooseHotContracts(contracts: Contract[]) {
const fiveMinutes = 5 * 60 * 1000
const seed = Math.round(Date.now() / fiveMinutes).toString()
shuffle(contracts, createRNG(seed))
return contracts.slice(0, 4)
}
export function listenForHotContracts( export function listenForHotContracts(
setHotContracts: (contracts: Contract[]) => void setHotContracts: (contracts: Contract[]) => void
) { ) {
return listenForValues<Contract>(hotContractsQuery, setHotContracts) return listenForValues<Contract>(hotContractsQuery, (contracts) =>
setHotContracts(chooseHotContracts(contracts))
)
} }
export function getHotContracts() { export function getHotContracts() {
return getValues<Contract>(hotContractsQuery) return getValues<Contract>(hotContractsQuery).then(chooseHotContracts)
} }

View File

@ -17,6 +17,7 @@ import {
import { Col } from '../components/layout/col' import { Col } from '../components/layout/col'
import { ContractCard } from '../components/contract-card' import { ContractCard } from '../components/contract-card'
import { Bet, listAllBets } from '../lib/firebase/bets' import { Bet, listAllBets } from '../lib/firebase/bets'
import { useHotContracts } from '../hooks/use-contracts'
export async function getStaticProps() { export async function getStaticProps() {
const [contracts, hotContracts, recentComments] = await Promise.all([ const [contracts, hotContracts, recentComments] = await Promise.all([
@ -51,12 +52,9 @@ const Home = (props: {
activeContractComments: Comment[][] activeContractComments: Comment[][]
hotContracts: Contract[] hotContracts: Contract[]
}) => { }) => {
const { const { activeContracts, activeContractBets, activeContractComments } = props
hotContracts,
activeContracts, const hotContracts = useHotContracts() ?? props.hotContracts
activeContractBets,
activeContractComments,
} = props
return ( return (
<Page> <Page>
@ -73,6 +71,8 @@ const Home = (props: {
const HotMarkets = (props: { hotContracts: Contract[] }) => { const HotMarkets = (props: { hotContracts: Contract[] }) => {
const { hotContracts } = props const { hotContracts } = props
if (hotContracts.length < 4) return <></>
const [c1, c2, c3, c4] = hotContracts const [c1, c2, c3, c4] = hotContracts
return ( return (