Skip to content

Commit d99ec38

Browse files
committed
Improved persistence and blockchain initialization
* Storing as binary using pickle * Added error handling * Updated blockchain initialize logic only when save file not found
1 parent 795d8c5 commit d99ec38

File tree

1 file changed

+67
-40
lines changed

1 file changed

+67
-40
lines changed

blockchain.py

Lines changed: 67 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from functools import reduce
22
from collections import OrderedDict
3-
import json
3+
# import json
4+
import pickle
45

56
from hash_util import hash_block, hash_str_256
67

@@ -11,16 +12,11 @@
1112
# Configure Proof-Of-Work Difficulty: Number of leading zeros required in the hash
1213
POW_LEADING_ZEROS = 2
1314

14-
# Initializing blockchain list with Genesis (first) block
15-
GENESIS_BLOCK = {
16-
'previous_hash': '', # Not required as it is the Genesis (first) block
17-
'index': 0,
18-
'transactions': [],
19-
'proof': 0 # Dummy proof (not required)
20-
}
21-
blockchain = [GENESIS_BLOCK]
15+
# The Blockchain: a list of blocks of processed transactions
16+
blockchain = []
2217

23-
# List of new transactions that are waiting to be processed (mined), i.e, included into the blockchain
18+
# List of new unhandled transactions that are waiting to be processed (mined)
19+
# and included into the blockchain
2420
open_transactions = []
2521

2622
# Current user
@@ -32,43 +28,74 @@
3228

3329

3430
def load_data():
35-
"""Loads the blockchain and the open-transactions data from the file"""
36-
with open('blockchain.txt', mode='r') as f:
37-
file_content = f.readlines()
38-
global blockchain
39-
global open_transactions
40-
41-
blockchain = json.loads(file_content[0][:-1]) # Exclude '\n' at the end of the line
42-
updated_blockchain = []
43-
for block in blockchain:
44-
updated_block = {
45-
'previous_hash': block['previous_hash'],
46-
'index': block['index'],
47-
'transactions': [OrderedDict(
48-
[('sender', tx['sender']), ('recipient', tx['recipient']), ('amount', tx['amount'])]) for tx in block['transactions']],
49-
'proof': block['proof']
50-
}
51-
updated_blockchain.append(updated_block)
52-
blockchain = updated_blockchain
31+
"""Loads the blockchain and the open-transactions data from file"""
32+
global blockchain
33+
global open_transactions
5334

54-
open_transactions = json.loads(file_content[1])
55-
updated_open_transactions = []
56-
for tx in open_transactions:
57-
updated_transaction = OrderedDict(
58-
[('sender', tx['sender']), ('recipient', tx['recipient']), ('amount', tx['amount'])])
59-
updated_open_transactions.append(updated_transaction)
60-
open_transactions = updated_open_transactions
35+
try:
36+
with open('blockchain_store.p', mode='rb') as f:
37+
file_content = pickle.loads(f.read())
38+
blockchain = file_content['blockchain']
39+
open_transactions = file_content['open_transactions']
40+
41+
## LOAD FROM TEXT FILE FOR EASIER DEBUGGING...
42+
# with open('blockchain_store.txt', mode='r') as f:
43+
# file_content = f.readlines()
44+
# blockchain = json.loads(file_content[0][:-1]) # Exclude '\n' at the end of the line
45+
# updated_blockchain = []
46+
# for block in blockchain:
47+
# updated_block = {
48+
# 'previous_hash': block['previous_hash'],
49+
# 'index': block['index'],
50+
# 'transactions': [OrderedDict(
51+
# [('sender', tx['sender']), ('recipient', tx['recipient']), ('amount', tx['amount'])]) for tx in block['transactions']],
52+
# 'proof': block['proof']
53+
# }
54+
# updated_blockchain.append(updated_block)
55+
# blockchain = updated_blockchain
56+
# open_transactions = json.loads(file_content[1])
57+
# updated_open_transactions = []
58+
# for tx in open_transactions:
59+
# updated_transaction = OrderedDict(
60+
# [('sender', tx['sender']), ('recipient', tx['recipient']), ('amount', tx['amount'])])
61+
# updated_open_transactions.append(updated_transaction)
62+
# open_transactions = updated_open_transactions
63+
64+
except (IOError, IndexError):
65+
print('Blockchain save file not found!')
66+
# Initializing blockchain list with Genesis (first) block
67+
GENESIS_BLOCK = {
68+
'previous_hash': '', # Not required as it is the Genesis (first) block
69+
'index': 0,
70+
'transactions': [],
71+
'proof': 0 # Dummy proof (not required)
72+
}
73+
blockchain = [GENESIS_BLOCK]
74+
# Initialize open-transactions
75+
open_transactions = []
6176

6277

6378
load_data() # Load Data as soon as the program starts
6479

6580

6681
def save_data():
67-
"""Saves the blockchain and the open-transactions data into a file"""
68-
with open('blockchain.txt', mode='w') as f:
69-
f.write(json.dumps(blockchain))
70-
f.write('\n')
71-
f.write(json.dumps(open_transactions))
82+
"""Saves the blockchain and the open-transactions data into file"""
83+
try:
84+
with open('blockchain_store.p', mode='wb') as f:
85+
save_data = {
86+
'blockchain': blockchain,
87+
'open_transactions': open_transactions
88+
}
89+
f.write(pickle.dumps(save_data))
90+
91+
## STORE IN A TEXT FILE FOR EASIER DEBUGGING...
92+
# with open('blockchain_store.txt', mode='w') as f:
93+
# f.write(json.dumps(blockchain))
94+
# f.write('\n')
95+
# f.write(json.dumps(open_transactions))
96+
97+
except IOError:
98+
print('Saving blockchain failed!')
7299

73100

74101
def valid_proof(transaction, last_hash, proof):

0 commit comments

Comments
 (0)