-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBlock.py
114 lines (88 loc) · 3.47 KB
/
Block.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
# reference - https://developer.ibm.com/technologies/blockchain/tutorials/develop-a-blockchain-application-from-scratch-in-python/
import copy
import json
from hashlib import sha256
class Block:
def __init__(self, idx, previous_block_hash=None, transactions=None, nonce=0, miner_rsa_pub_key=None, mined_by=None, mining_rewards=None, hash=None, signature=None):
self._idx = idx
self._previous_block_hash = previous_block_hash
self._transactions = transactions
self._nonce = nonce
# miner specific
self._miner_rsa_pub_key = miner_rsa_pub_key
self._mined_by = mined_by
self._mining_rewards = mining_rewards
# validator specific
# self._is_validator_block = is_validator_block
# the hash of the current block, calculated by compute_hash
self._hash = hash
self._signature = signature
#for proof_of_endorsement
self.leader_id = None
self.max_candidate_model_accuracy = None
# compute_hash() also used to return value for block verification
# if False by default, used for pow and verification, in which hash has to be None, because at this moment -
# pow - block hash is None, so does not affect much
# verification - the block already has its hash
# if hash_entire_block == True -> used in set_previous_block_hash, where we need to hash the whole previous block
def compute_hash(self, hash_entire_block=False):
block_content = copy.deepcopy(self.__dict__)
if not hash_entire_block:
block_content['_hash'] = None
block_content['_signature'] = None
block_content['_mining_rewards'] = None
# need sort keys to preserve order of key value pairs
return sha256(str(sorted(block_content.items())).encode('utf-8')).hexdigest() #十六进制字符串
def remove_signature_for_verification(self):
self._signature = None
def set_hash(self, the_hash):
self._hash = the_hash
def nonce_increment(self):
self._nonce += 1
# returners of the private attributes
def return_previous_block_hash(self):
return self._previous_block_hash
def return_block_idx(self):
return self._idx
def return_hash(self):
return self._hash
def return_miner_rsa_pub_key(self):
return self._miner_rsa_pub_key
''' Miner Specific '''
def set_previous_block_hash(self, hash_to_set):
self._previous_block_hash = hash_to_set
def add_verified_transaction(self, transaction):
# after verified in cross_verification()
# transactions can be both workers' or validators' transactions
self._transactions.append(transaction)
def set_nonce(self, nonce):
self._nonce = nonce
def set_mined_by(self, mined_by):
self._mined_by = mined_by
def return_mined_by(self):
return self._mined_by
def set_signature(self, signature):
# signed by mined_by node
self._signature = signature
def return_signature(self):
return self._signature
def set_mining_rewards(self, mining_rewards):
self._mining_rewards = mining_rewards
def set_leader_id(self, leader_id):
self.leader_id = leader_id
def set_max_candidate_model_accuracy(self, max_candidate_model_accuracy):
self.max_candidate_model_accuracy = max_candidate_model_accuracy
def return_leader_id(self):
return self.leader_id
def return_max_candidate_model_accuracy(self):
return self.max_candidate_model_accuracy
def return_mining_rewards(self):
return self._mining_rewards
def return_transactions(self):
return self._transactions
# a temporary workaround to free GPU mem by delete txs stored in the blocks. Not good when need to resync chain
def free_tx(self):
try:
del self._transactions
except:
pass