-
Notifications
You must be signed in to change notification settings - Fork 52
/
Copy pathwhitelist.py
91 lines (70 loc) · 2.58 KB
/
whitelist.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/usr/bin/env python3
import argparse
import random
from os import path
WHITELIST_NUM = 5000
# In case we have bad actors.
WHITELSIT_SUBSTITUTE_NUM = 500
def get_user_keys_and_scores() -> [(str, float)]:
"""KYC-cleared users with score >= 60."""
dir_path = path.dirname(path.realpath(__file__))
with open(path.join(dir_path, 'applicants.csv')) as f:
lines = f.readlines()
ret = []
# Skip header row.
for line in lines[1:]:
k, s = line.strip().split(',')
ret.append((k, float(s)))
return ret
def get_blacklisted_user_keys() -> [str]:
"""Get user keys who are blacklisted because of selling code, etc."""
dir_path = path.join(path.dirname(path.realpath(__file__)))
with open(path.join(dir_path, 'blacklist.txt')) as f:
ret = [line.strip() for line in f.readlines()]
return ret
class Candidate(object):
"""
A candidate is identified by the accees code. The score is the sum of:
1. Early supporter score. Max 30.
2. Quiz score. Max 50.
3. Contribution score. Max 20.
"""
def __init__(self, key: str, score: float):
self.key = key
self.score = score
def main():
parser = argparse.ArgumentParser()
# Use a certain blockhash as the random seed.
parser.add_argument(
'seed', type=str, help='Use a certain blockhash as the random seed.')
args = parser.parse_args()
random.seed(args.seed)
blacklisted_users = set(get_blacklisted_user_keys())
# Get KYC-cleared users with scores >= 60.
users_and_scores = get_user_keys_and_scores()
candidates = [
Candidate(k, s)
for k, s in users_and_scores
if k not in blacklisted_users
]
whitelist = []
assert len(candidates) > WHITELIST_NUM + WHITELSIT_SUBSTITUTE_NUM
# Make sure the order is deterministic so it's reproducible.
candidates.sort(key=lambda c: c.key)
for _ in range(WHITELIST_NUM + WHITELSIT_SUBSTITUTE_NUM):
# Sampling. The higher the score, the greater the chance to get picked.
total_score = sum(c.score for c in candidates)
chosen = random.random() * total_score
for i, c in enumerate(candidates):
if chosen <= c.score:
whitelist.append(c)
candidates.pop(i)
break
chosen -= c.score
assert len(whitelist) == WHITELIST_NUM + WHITELSIT_SUBSTITUTE_NUM
for i, c in enumerate(whitelist):
if i == WHITELIST_NUM:
print('=============Below are substitutes=============')
print(c.key, c.score)
if __name__ == '__main__':
main()