-
Notifications
You must be signed in to change notification settings - Fork 5
/
fullNode.py
143 lines (93 loc) · 2.58 KB
/
fullNode.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
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
135
136
137
138
139
from duckchain import Blockchain
from flask import Flask, jsonify, request
import json
import schedule,threading
# instantiate the full node
app = Flask(__name__)
# instantiate the blockchain
blockchain = Blockchain()
@app.route('/list_blocks',methods=['get'])
def list_blocks():
"""
list all the blocks saved on the node
"""
return jsonify(blockchain.blocks),200
@app.route('/full/register_node/',methods=['post'])
def register_node():
values = request.get_data()
values = json.loads(values)
address = values['address']
if (address is not None) and (address not in blockchain.nodes_list):
blockchain.nodes_list.append(address)
response = {
"back":"ok",
"nodes_list":blockchain.nodes_list
}
else:
response = {
"back":"wrong vars or node existed"
}
return jsonify(response), 201
@app.route('/full/list_nodes/',methods=['get'])
def list_nodes():
"""
list all the nodes address
"""
response = blockchain.nodes_list
return jsonify(response), 200
@app.route('/full/validate_block/',methods=['get'])
def validate_new_block():
"""
as full node , validate the proof which mining nodes submit
"""
proof = request.values.get('proof')
if (proof is not None ) and len(blockchain.blocks) is not 0:
previous_block = blockchain.blocks[-1]
if blockchain.validate_proof( int(proof) ,previous_block):
# proof is valid
reason = "ok"
else:
reason = "failed,try later!"
else:
reason = "full node need to load chains,try later!"
response = {
"reason": reason
}
return jsonify(response), 200
def sync_blocks():
"""
sync blocks with other registered node,if any blocks on these nodes is longer,update local blockchain
"""
address_list = blockchain.nodes_list
whether_update = False
for node_url in address_list:
full_url = node_url + "/list_blocks"
node_blocks = blockchain.loadUrl(full_url)
if node_blocks == "wrong":
print "died node :" + node_url
continue
if len(node_blocks) > len(blockchain.blocks):
whether_update = True
blockchain.blocks = node_blocks
if whether_update:
add_str = "chain updated to length: " + str(len(blockchain.blocks))
else:
add_str = "no changes"
response = {
"status": "compared :" + str(len(address_list)) + " nodes, " + add_str
}
print(response)
def run_app():
"""
start server
"""
app.run(host='0.0.0.0', port=5000)
if __name__ == "__main__":
# mine genesis block
blockchain.generate_genesis_block()
# run server
threading.Thread(target=run_app).start()
# sync blockchain every 10 seconds
schedule.every(10).seconds.do(sync_blocks)
while True:
schedule.run_pending()