-
Notifications
You must be signed in to change notification settings - Fork 60
Expand file tree
/
Copy pathpeer.py
More file actions
134 lines (112 loc) · 3.84 KB
/
peer.py
File metadata and controls
134 lines (112 loc) · 3.84 KB
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/env python
import asyncio
from hashlib import sha256
from random import choice
import json
from datetime import datetime
from blockchain.block import generate_block, is_block_valid, caculate_hash
from common.settings import validators, Blockchain, tempblocks
candidate_blocks = asyncio.Queue()
announcements = asyncio.Queue()
async def handle_conn(reader, writer):
client_host, client_port = writer.get_extra_info('peername')
addr = "".join([client_host, ":", str(client_port)])
print("Got connection from ", addr)
# 提示客户端输入balance数量
writer.write(b"Enter token balance:")
await writer.drain()
balance_enc = await reader.read(100)
try:
balance = int(balance_enc.decode())
except Exception as e:
print(e)
address = sha256(addr.encode()).hexdigest()
validators[address] = balance
print(validators)
# asyncio.ensure_future(run())
await run()
while True:
writer.write(b"Enter a new BPM:")
await writer.drain()
bpm_code = await reader.read(100)
print("----", bpm_code)
try:
bpm = int(bpm_code.decode())
except Exception as e:
print(e)
del validators[address]
break
last_block = Blockchain[-1]
new_block = generate_block(last_block, bpm, address)
if is_block_valid(new_block, last_block):
print("new block is valid!")
await candidate_blocks.put(new_block)
writer.write(b"Enter a new BPM:\n")
try:
winner = await announcements.get()
writer.write(winner.encode())
writer.write(b'\n')
await writer.drain()
except asyncio.QueueEmpty:
pass
except IOError:
pass
try:
bc = json.dumps(Blockchain)
writer.write(bc.encode())
await writer.drain()
except IOError:
pass
async def pick_winner(announcements):
"""
选择记账人
"""
while True:
await asyncio.sleep(1)
lottery_pool = [] #
temp = tempblocks
if temp:
for block in temp:
if block["Validator"] not in lottery_pool:
set_validator = validators
k = set_validator.get(block["Validator"])
# 根据持有的token数量构建票池, 持有的token数量与出现次数成正比
if k:
for _ in range(k):
lottery_pool.append(block["Validator"])
if not lottery_pool:
# No eligible validator in this round; skip instead of crashing on choice([]).
tempblocks.clear()
continue
lottery_winner = choice(lottery_pool)
print(lottery_winner)
for block in temp:
if block["Validator"] == lottery_winner:
Blockchain.append(block)
# write msg in announcement queue
msg = '\n {0} 赢得了记账权利'.format(lottery_winner)
await announcements.put(msg)
break
tempblocks.clear()
async def candidate(candidate_blocks):
while True:
try:
candi = await candidate_blocks.get()
except asyncio.QueueEmpty:
await asyncio.sleep(1)
pass
tempblocks.append(candi)
async def run():
t = str(datetime.now())
genesis_block = {
"Index": 0,
"Timestamp": t,
"BPM": 0,
"PrevHash": "",
"Validator": ""
}
genesis_block["Hash"] = caculate_hash(genesis_block)
Blockchain.append(genesis_block)
print(Blockchain)
asyncio.ensure_future(candidate(candidate_blocks))
asyncio.ensure_future(pick_winner(announcements))