1313
1414
1515
16+ def resp (status_code = 200 , message = 'Success' , data = None ):
17+ """Helper function to return jsonified response"""
18+ response = { 'message' : message }
19+ if data :
20+ response .update (data )
21+ return jsonify (response ), status_code
22+
23+
1624def validate_request_data (data , required_fields = None ):
1725 """Helper function to validates the request data.
1826 returns None if data is valid, i.e., data is present and
1927 required_fields, if any, are also present.
20- Otherwise, returns a jsonify() response object with 400 status.
28+ Otherwise, returns a jsonified response object
29+ with 400 status and an error message.
2130
2231 Arguments:
2332 :data: Dictionary of request parameters to validate
2433 :required_fields: List of fields that are required to be present
2534 """
2635 if not data :
27- response = {'message' : 'No data found' }
28- return jsonify (response ), 400
36+ return resp (400 , 'No data found' )
2937 if required_fields :
3038 if not all (field in data for field in required_fields ):
31- response = {'message' : 'Required data is misssing' }
32- return jsonify (response ), 400
39+ return resp (400 , 'Required data is misssing' )
3340 return None
3441
3542
@@ -54,10 +61,7 @@ def get_transactions():
5461def add_transaction ():
5562 """TODO: Validate input parameters"""
5663 if wallet .public_key == None :
57- response = {
58- 'message' : 'No wallet set up.'
59- }
60- return jsonify (response ), 400
64+ return resp (400 , 'No wallet set up' )
6165
6266 data = request .get_json ()
6367 required_fields = ['recipient' , 'amount' ]
@@ -70,20 +74,15 @@ def add_transaction():
7074 signature = wallet .sign_transactions (wallet .public_key , recipient , amount )
7175 success = blockchain .add_transaction (sender = wallet .public_key , recipient = recipient , amount = amount , signature = signature )
7276 if success :
73- response = {
74- 'message' : 'Transaction added successfully.' ,
75- 'transaction' : blockchain .get_open_transactions ()[- 1 ].to_dict (),
76- 'balance' : blockchain .get_balance ()
77- }
78- return jsonify (response ), 201
77+ return resp (201 , 'Transaction added successfully.' , {
78+ 'transaction' : blockchain .get_open_transactions ()[- 1 ].to_dict (),
79+ 'balance' : blockchain .get_balance ()
80+ })
7981 else :
80- response = {
81- 'message' : 'Failed to create a transaction'
82- }
83- return jsonify (response ), 500
82+ return resp (500 , 'Failed to create a transaction' )
8483
8584
86- @app .route ('/broadcast_transaction ' , methods = ['POST' ])
85+ @app .route ('/broadcast-transaction ' , methods = ['POST' ])
8786def broadcast_transaction ():
8887 """Receive broadcast of newly added transactions from other nodes"""
8988 data = request .get_json ()
@@ -94,20 +93,15 @@ def broadcast_transaction():
9493
9594 success = blockchain .add_transaction (sender = data ['sender' ], recipient = data ['recipient' ], amount = data ['amount' ], signature = data ['signature' ], is_receiving = True )
9695 if success :
97- response = {
98- 'message' : 'Transaction added successfully.' ,
99- 'transaction' : blockchain .get_open_transactions ()[- 1 ].to_dict (),
100- 'balance' : blockchain .get_balance ()
101- }
102- return jsonify (response ), 201
96+ return resp (201 , 'Transaction added successfully.' , {
97+ 'transaction' : blockchain .get_open_transactions ()[- 1 ].to_dict (),
98+ 'balance' : blockchain .get_balance ()
99+ })
103100 else :
104- response = {
105- 'message' : 'Failed to create a transaction'
106- }
107- return jsonify (response ), 500
101+ return resp (500 , 'Failed to create a transaction.' )
108102
109103
110- @app .route ('/broadcast_block ' , methods = ['POST' ])
104+ @app .route ('/broadcast-block ' , methods = ['POST' ])
111105def broadcast_block ():
112106 """Receive broadcast of newly mined blocks from other nodes"""
113107 data = request .get_json ()
@@ -120,17 +114,25 @@ def broadcast_block():
120114 last_local_block_index = blockchain .get_last_block ()['index' ]
121115 if block ['index' ] == last_local_block_index + 1 :
122116 if blockchain .add_block (block ):
123- response = {'message' : 'Block added successfully' }
124- return jsonify (response ), 201
117+ return resp (201 , 'Block added successfully.' )
125118 else :
126- response = {'message' : 'Block seems invalid' }
127- return jsonify (response ), 500
119+ return resp (409 , 'Block seems invalid.' ) # Invalid data (conflict)
128120 elif block ['index' ] > last_local_block_index :
129- pass
121+ # TODO: Our chain is shorter.. We need to fix it!
122+ blockchain .resolve_conflicts = True
123+ return resp (200 , 'Bockchain seems to differ from local blockchain.' ) # Not an error (Current node needs to fix the issue)
130124 else :
131125 # Our blockchain is more recent (has longer chain)
132- response = {'message' : 'Bockchain seems to be shorter. Block not added' }
133- return jsonify (response ), 409 # Invalid data
126+ return resp (409 , 'Bockchain seems to be shorter. Block not added.' ) # Invalid data (conflict)
127+
128+
129+ @app .route ('/resolve-conflicts' , methods = ['POST' ])
130+ def resolve_conflicts ():
131+ replaced = blockchain .resolve ()
132+ if replaced :
133+ return resp (200 , 'Chain was replaced.' )
134+ else :
135+ return resp (200 , 'Local chain kept.' )
134136
135137
136138@app .route ('/wallet' , methods = ['POST' ])
@@ -139,70 +141,57 @@ def create_keys():
139141 if wallet .save_keys ():
140142 global blockchain
141143 blockchain = Blockchain (wallet .public_key )
142- response = {
143- 'public_key' : wallet .public_key ,
144- 'private_key' : wallet .private_key ,
145- 'balance' : blockchain .get_balance ()
146- }
147- return jsonify (response ), 201
144+ return resp (201 , '' , {
145+ 'public_key' : wallet .public_key ,
146+ 'private_key' : wallet .private_key ,
147+ 'balance' : blockchain .get_balance ()
148+ })
148149 else :
149- response = {
150- 'message' : 'Failed to save the wallet keys.'
151- }
152- return jsonify (response ), 500
150+ return resp (500 , 'Failed to save the wallet keys.' )
153151
154152
155153@app .route ('/wallet' , methods = ['GET' ])
156154def load_keys ():
157155 if wallet .load_keys ():
158156 global blockchain
159157 blockchain = Blockchain (wallet .public_key )
160- response = {
161- 'public_key' : wallet .public_key ,
162- 'private_key' : wallet .private_key ,
163- 'balance' : blockchain .get_balance ()
164- }
165- return jsonify (response ), 200
158+ return resp (200 , '' , {
159+ 'public_key' : wallet .public_key ,
160+ 'private_key' : wallet .private_key ,
161+ 'balance' : blockchain .get_balance ()
162+ })
166163 else :
167- response = {
168- 'message' : 'Failed to load the wallet keys.'
169- }
170- return jsonify (response ), 500
164+ return resp (500 , 'Failed to load the wallet keys.' )
171165
172166
173167@app .route ('/balance' , methods = ['GET' ])
174168def get_balance ():
175169 balance = blockchain .get_balance ()
176170 if balance != None :
177- response = {
178- 'message' : 'Balance fetched successfully' ,
179- 'balance' : blockchain .get_balance ()
180- }
181- return jsonify (response ), 200
171+ return resp (200 , 'Balance fetched successfully.' , {
172+ 'balance' : blockchain .get_balance ()
173+ })
182174 else :
183- response = {
184- 'message' : 'Failed to load balance.' ,
185- 'is_wallet_setup' : wallet .public_key != None
186- }
187- return jsonify (response ), 500
175+ return resp (500 , 'Failed to load balance.' , {
176+ 'is_wallet_setup' : wallet .public_key != None
177+ })
188178
189179
190180@app .route ('/mine' , methods = ['POST' ])
191181def mine ():
182+ if blockchain .resolve_conflicts :
183+ return resp (409 , 'Block not added due to conflicts.' )
184+
192185 block = blockchain .mine_block ()
193186 if block != None :
194- response = {
195- 'message' : 'Mining successful. Block added.' ,
196- 'added_block' : block .to_dict (),
197- 'balance' : blockchain .get_balance ()
198- }
199- return jsonify (response ), 201
187+ return resp (201 , 'Mining successful. Block added.' , {
188+ 'added_block' : block .to_dict (),
189+ 'balance' : blockchain .get_balance ()
190+ })
200191 else :
201- response = {
202- 'message' : 'Mining failed. Block not added.' ,
203- 'is_wallet_setup' : wallet .public_key != None
204- }
205- return jsonify (response ), 500
192+ return resp (500 , 'Mining failed. Block not added.' , {
193+ 'is_wallet_setup' : wallet .public_key != None
194+ })
206195
207196
208197@app .route ('/chain' , methods = ['GET' ])
@@ -212,10 +201,9 @@ def get_chain():
212201
213202@app .route ('/nodes' , methods = ['GET' ])
214203def get_nodes ():
215- response = {
216- 'peer_nodes' : blockchain .get_peer_nodes ()
217- }
218- return jsonify (response ), 200
204+ return resp (200 , '' , {
205+ 'peer_nodes' : blockchain .get_peer_nodes ()
206+ })
219207
220208
221209@app .route ('/node' , methods = ['POST' ])
@@ -227,26 +215,19 @@ def add_node():
227215 return invalid_data_response
228216
229217 blockchain .add_peer_node (data ['node' ])
230- response = {
231- 'message' : 'Node added successfully' ,
232- 'peer_nodes' : blockchain .get_peer_nodes ()
233- }
234- return jsonify (response ), 201
218+ return resp (201 , 'Node added successfully.' , {
219+ 'peer_nodes' : blockchain .get_peer_nodes ()
220+ })
235221
236222
237223@app .route ('/node/<node_url>' , methods = ['DELETE' ])
238224def remove_node (node_url ):
239225 if not node_url :
240- response = {
241- 'message' : 'No node data found'
242- }
243- return jsonify (response ), 400
226+ return resp (400 , 'No node data found' )
244227 blockchain .remove_peer_node (node_url )
245- response = {
246- 'message' : 'Node removed successfully' ,
247- 'peer_nodes' : blockchain .get_peer_nodes ()
248- }
249- return jsonify (response ), 200
228+ return resp (200 , 'Node removed successfully.' , {
229+ 'peer_nodes' : blockchain .get_peer_nodes ()
230+ })
250231
251232
252233
0 commit comments