-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathConsensus.py
107 lines (79 loc) · 2.69 KB
/
Consensus.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
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Apr 3 14:28:18 2019
@author: jisu
"""
import hashlib, Block, random, BlockChain
random.seed(0)
def min_hash(ids):
"""Performs a slightly modified Minhash correlated sampling
Parameters:
ids (list): List of tx ids
Returns:
list: A sorted list of sha256 hashvalues of ids
"""
def hash_data(data):
hasher = hashlib.sha256(data.encode())
return hasher.hexdigest()
return sorted(hash_data(i) for i in ids)
def fill_prio_dict(ids, prios):
"""Places tx ids in a dict grouped by their priority values
Parameters:
ids (list): List of tx ids
prios (list): List of tx priorities
Returns:
dict: {tx_priority : [tx_id1, tx_id2, ...]}
"""
prio_dict = {}
for p_type in Block.prio_types:
prio_dict[p_type] = []
for i, p in zip(ids, prios):
prio_dict[p].append(i)
return prio_dict
def priority_sort(ids, prios):
"""Sorts tx ids by their priority
Parameters:
ids (list): List of tx ids
prios (list): List of tx priorities
Returns:
list: The tx ids sorted by priority
"""
prio_dict = fill_prio_dict(ids, prios)
block_proposal = [min_hash(v) for v in prio_dict.values()]
#change priority in list from lowest -> highest to highest -> lowest
block_proposal.reverse()
#return flattened list (there is one list for each priority type in the block proposal)
return [v for prio_type in block_proposal for v in prio_type]
def consistency(block_a, block_b):
"""Calculates the similarity of two blocks
Parameters:
block_a, block_b (Block): the blocks to compare
Returns:
int: The number of tx ids unique to either of the blocks
"""
tx_a = set(block_a.get_tx())
tx_b = set(block_b.get_tx())
return len(tx_a ^ tx_b)
#TODO: replace with netstats later
def netsize():
return 9
#Using PBFT for consistency in each round
def consensus_reached(proposals):
"""PBFT consensus check on a list of block proposals
TODO: Needs to be changed to allow similar blocks for consensus
Parameters:
proposals: List of block proposals
Returns:
True: at least 2/3 of network nodes have proposed identical blocks
False: otherwise
"""
# If there are not at least 2/3 network size block proposals, there cannot be a consensus
if len(proposals) < netsize() * 2 // 3:
return False
for p in proposals:
#TODO: replace count by consistency based count
if proposals.count(p) >= netsize() * 2 // 3:
#TODO: write consensus result to some location
return True
return False