Skip to content

Commit ced1050

Browse files
author
Sergey Khoroshavin
committed
INDY-1199: Improve logic of inconsistency watcher
Signed-off-by: Sergey Khoroshavin <[email protected]>
1 parent 47e2bd1 commit ced1050

File tree

2 files changed

+31
-10
lines changed

2 files changed

+31
-10
lines changed

plenum/server/inconsistency_watchers.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,21 @@
44

55
class NetworkInconsistencyWatcher:
66
def __init__(self, cb: Callable):
7-
self._nodes = set()
8-
self.connected = set()
97
self.callback = cb
10-
self.quorums = Quorums(0)
8+
self._nodes = set()
9+
self._connected = set()
10+
self._quorums = Quorums(0)
11+
self._reached_consensus = False
1112

1213
def connect(self, name: str):
13-
self.connected.add(name)
14+
self._connected.add(name)
15+
if self._quorums.strong.is_reached(len(self._connected)):
16+
self._reached_consensus = True
1417

1518
def disconnect(self, name: str):
16-
had_consensus = self._has_consensus()
17-
self.connected.discard(name)
18-
if had_consensus and not self._has_consensus():
19+
self._connected.discard(name)
20+
if self._reached_consensus and not self._quorums.weak.is_reached(len(self._connected)):
21+
self._reached_consensus = False
1922
self.callback()
2023

2124
@property
@@ -24,7 +27,7 @@ def nodes(self):
2427

2528
def set_nodes(self, nodes: Iterable[str]):
2629
self._nodes = set(nodes)
27-
self.quorums = Quorums(len(self._nodes))
30+
self._quorums = Quorums(len(self._nodes))
2831

2932
def _has_consensus(self):
30-
return self.quorums.weak.is_reached(len(self.connected))
33+
return self._quorums.weak.is_reached(len(self._connected))

plenum/test/restart/test_network_inconsistency_watcher.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,26 @@ def test_watcher_is_not_triggered_when_just_one_node_connects_and_disconnects(wa
5656
def test_watcher_is_triggered_when_going_below_consensus(watcher: NetworkInconsistencyWatcher):
5757
watcher.connect('Alpha')
5858
watcher.connect('Beta')
59+
watcher.connect('Gamma')
5960
watcher.disconnect('Beta')
61+
watcher.disconnect('Gamma')
6062

6163
assert watcher.callback.call_count == 1
6264

6365

66+
def test_watcher_is_not_triggered_when_going_below_consensus_without_going_above_strong_quorum(watcher: NetworkInconsistencyWatcher):
67+
watcher.connect('Alpha')
68+
watcher.connect('Beta')
69+
watcher.disconnect('Beta')
70+
71+
assert watcher.callback.call_count == 0
72+
73+
6474
def test_watcher_is_not_triggered_when_adding_nodes_while_on_edge_of_consensus(watcher: NetworkInconsistencyWatcher):
6575
watcher.connect('Alpha')
6676
watcher.connect('Beta')
77+
watcher.connect('Gamma')
78+
watcher.disconnect('Gamma')
6779
_add_node(watcher, 'Epsilon')
6880
_add_node(watcher, 'Zeta')
6981
_add_node(watcher, 'Eta')
@@ -84,18 +96,24 @@ def test_watcher_is_not_triggered_when_removing_nodes_below_minimum_count(watche
8496
def test_watcher_is_not_triggered_when_removing_nodes_and_going_below_consensus(watcher: NetworkInconsistencyWatcher):
8597
_add_node(watcher, 'Theta')
8698
watcher.connect('Alpha')
99+
watcher.connect('Beta')
100+
watcher.connect('Gamma')
87101
watcher.connect('Theta')
102+
watcher.disconnect('Beta')
103+
watcher.disconnect('Gamma')
88104
_remove_node(watcher, 'Theta')
89105

90106
assert watcher.callback.call_count == 0
91107

92108

93-
def test_watcher_is_not_triggered_when_just_two_nodes_connect_and_disconnect_in_7_node_pool(
109+
def test_watcher_is_not_triggered_when_just_three_nodes_connect_and_disconnect_in_7_node_pool(
94110
watcher: NetworkInconsistencyWatcher):
95111
watcher.set_nodes(['Alpha', 'Beta', 'Gamma', 'Delta', 'Epsilon', 'Zeta', 'Eta'])
96112
watcher.connect('Alpha')
97113
watcher.connect('Beta')
114+
watcher.connect('Gamma')
98115
watcher.disconnect('Alpha')
99116
watcher.disconnect('Beta')
117+
watcher.disconnect('Gamma')
100118

101119
assert watcher.callback.call_count == 0

0 commit comments

Comments
 (0)