mirror of
https://github.com/logos-co/nomos-specs.git
synced 2025-02-08 21:43:48 +00:00
Refactor EntropyOverlay and usages
This commit is contained in:
parent
9ae2f99b5c
commit
5bfdacc213
@ -18,7 +18,6 @@ class BeaconizedCarnot(Carnot):
|
|||||||
self.random_beacon = RandomBeaconHandler(
|
self.random_beacon = RandomBeaconHandler(
|
||||||
RecoveryMode.generate_beacon(entropy, -1)
|
RecoveryMode.generate_beacon(entropy, -1)
|
||||||
)
|
)
|
||||||
overlay.set_entropy(self.random_beacon.last_beacon.entropy())
|
|
||||||
super().__init__(self.pk, overlay=overlay)
|
super().__init__(self.pk, overlay=overlay)
|
||||||
|
|
||||||
def approve_block(self, block: BeaconizedBlock, votes: Set[Vote]) -> Event:
|
def approve_block(self, block: BeaconizedBlock, votes: Set[Vote]) -> Event:
|
||||||
@ -45,13 +44,13 @@ class BeaconizedCarnot(Carnot):
|
|||||||
# root members send votes to next leader, we update our beacon first
|
# root members send votes to next leader, we update our beacon first
|
||||||
if self.overlay.is_member_of_root_committee(self.id):
|
if self.overlay.is_member_of_root_committee(self.id):
|
||||||
assert(self.random_beacon.verify_happy(block.beacon, block.pk, block.qc.view))
|
assert(self.random_beacon.verify_happy(block.beacon, block.pk, block.qc.view))
|
||||||
self.overlay.set_entropy(self.random_beacon.last_beacon.entropy())
|
self.overlay = self.overlay.advance(self.random_beacon.last_beacon.entropy())
|
||||||
return Send(to=self.overlay.leader(), payload=vote)
|
return Send(to=self.overlay.leader(), payload=vote)
|
||||||
|
|
||||||
# otherwise we send to the parent committee and update the beacon second
|
# otherwise we send to the parent committee and update the beacon second
|
||||||
return_event = Send(to=self.overlay.parent_committee(self.id), payload=vote)
|
return_event = Send(to=self.overlay.parent_committee(self.id), payload=vote)
|
||||||
assert(self.random_beacon.verify_happy(block.beacon, block.pk, block.qc.view))
|
assert(self.random_beacon.verify_happy(block.beacon, block.pk, block.qc.view))
|
||||||
self.overlay.set_entropy(self.random_beacon.last_beacon.entropy())
|
self.overlay = self.overlay.advance(self.random_beacon.last_beacon.entropy())
|
||||||
return return_event
|
return return_event
|
||||||
|
|
||||||
def receive_timeout_qc(self, timeout_qc: TimeoutQc):
|
def receive_timeout_qc(self, timeout_qc: TimeoutQc):
|
||||||
@ -60,7 +59,7 @@ class BeaconizedCarnot(Carnot):
|
|||||||
return
|
return
|
||||||
new_beacon = RecoveryMode.generate_beacon(self.random_beacon.last_beacon.entropy(), timeout_qc.view)
|
new_beacon = RecoveryMode.generate_beacon(self.random_beacon.last_beacon.entropy(), timeout_qc.view)
|
||||||
self.random_beacon.verify_unhappy(new_beacon, timeout_qc.view)
|
self.random_beacon.verify_unhappy(new_beacon, timeout_qc.view)
|
||||||
self.overlay.set_entropy(self.random_beacon.last_beacon.entropy())
|
self.overlay = self.overlay.advance(self.random_beacon.last_beacon.entropy())
|
||||||
|
|
||||||
def propose_block(self, view: View, quorum: Quorum) -> Event:
|
def propose_block(self, view: View, quorum: Quorum) -> Event:
|
||||||
event: Event = super().propose_block(view, quorum)
|
event: Event = super().propose_block(view, quorum)
|
||||||
|
@ -22,7 +22,7 @@ class FlatOverlay(EntropyOverlay):
|
|||||||
return random.choice(self.nodes)
|
return random.choice(self.nodes)
|
||||||
|
|
||||||
def advance(self, entropy: bytes):
|
def advance(self, entropy: bytes):
|
||||||
self.entropy = entropy
|
return FlatOverlay(self.next_leader(), self.nodes, entropy)
|
||||||
|
|
||||||
def is_leader(self, _id: Id):
|
def is_leader(self, _id: Id):
|
||||||
return _id == self.leader()
|
return _id == self.leader()
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import random
|
||||||
from typing import Dict, List
|
from typing import Dict, List
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
@ -5,21 +6,19 @@ from itertools import chain
|
|||||||
from blspy import PrivateKey
|
from blspy import PrivateKey
|
||||||
|
|
||||||
from carnot import Id, Carnot, Block, Overlay, Vote, StandardQc, NewView
|
from carnot import Id, Carnot, Block, Overlay, Vote, StandardQc, NewView
|
||||||
from beacon import generate_random_sk, RandomBeacon, NormalMode
|
from beacon import generate_random_sk, RandomBeacon, NormalMode, RecoveryMode
|
||||||
from beaconized_carnot import BeaconizedCarnot, BeaconizedBlock
|
from beaconized_carnot import BeaconizedCarnot, BeaconizedBlock
|
||||||
from overlay import FlatOverlay, EntropyOverlay
|
from overlay import FlatOverlay, EntropyOverlay
|
||||||
from test_unhappy_path import parents_from_childs
|
from test_unhappy_path import parents_from_childs
|
||||||
|
|
||||||
|
|
||||||
def gen_node(sk: PrivateKey, overlay: Overlay, entropy: bytes = b""):
|
def gen_node(sk: PrivateKey, overlay: Overlay, entropy: bytes = b""):
|
||||||
node = BeaconizedCarnot(sk, overlay)
|
node = BeaconizedCarnot(sk, overlay, entropy)
|
||||||
return node.id, node
|
return node.id, node
|
||||||
|
|
||||||
|
|
||||||
def succeed(nodes: Dict[Id, BeaconizedCarnot], proposed_block: BeaconizedBlock) -> (List[Vote], EntropyOverlay):
|
def succeed(nodes: Dict[Id, BeaconizedCarnot], proposed_block: BeaconizedBlock, overlay: EntropyOverlay) -> (List[Vote], EntropyOverlay):
|
||||||
overlay = FlatOverlay(list(nodes.keys()))
|
overlay = overlay.advance(proposed_block.beacon.entropy())
|
||||||
overlay.set_entropy(proposed_block.beacon.entropy())
|
|
||||||
|
|
||||||
# broadcast the block
|
# broadcast the block
|
||||||
for node in nodes.values():
|
for node in nodes.values():
|
||||||
node.receive_block(proposed_block)
|
node.receive_block(proposed_block)
|
||||||
@ -47,9 +46,8 @@ def succeed(nodes: Dict[Id, BeaconizedCarnot], proposed_block: BeaconizedBlock)
|
|||||||
return root_votes, overlay
|
return root_votes, overlay
|
||||||
|
|
||||||
|
|
||||||
def fail(nodes: Dict[Id, BeaconizedCarnot], proposed_block: BeaconizedBlock) -> (List[NewView], EntropyOverlay):
|
def fail(nodes: Dict[Id, BeaconizedCarnot], proposed_block: BeaconizedBlock, overlay: EntropyOverlay) -> (List[NewView], EntropyOverlay):
|
||||||
overlay = FlatOverlay(list(nodes.keys()))
|
overlay = overlay.advance(proposed_block.beacon.entropy())
|
||||||
overlay.set_entropy(proposed_block.beacon.entropy)
|
|
||||||
# broadcast the block
|
# broadcast the block
|
||||||
for node in nodes.values():
|
for node in nodes.values():
|
||||||
node.receive_block(proposed_block)
|
node.receive_block(proposed_block)
|
||||||
@ -106,7 +104,7 @@ def add_genesis_block(carnot: BeaconizedCarnot, sk: PrivateKey) -> Block:
|
|||||||
carnot.receive_block(genesis_block)
|
carnot.receive_block(genesis_block)
|
||||||
carnot.local_high_qc = genesis_block.qc
|
carnot.local_high_qc = genesis_block.qc
|
||||||
carnot.current_view = 1
|
carnot.current_view = 1
|
||||||
carnot.overlay.set_entropy(beacon.entropy())
|
carnot.overlay = carnot.overlay.advance(beacon.entropy())
|
||||||
return genesis_block
|
return genesis_block
|
||||||
|
|
||||||
|
|
||||||
@ -114,10 +112,14 @@ def initial_setup(test_case: TestCase, size: int) -> (Dict[Id, Carnot], Carnot,
|
|||||||
keys = [generate_random_sk() for _ in range(size)]
|
keys = [generate_random_sk() for _ in range(size)]
|
||||||
nodes_ids = [bytes(key.get_g1()) for key in keys]
|
nodes_ids = [bytes(key.get_g1()) for key in keys]
|
||||||
genesis_sk = generate_random_sk()
|
genesis_sk = generate_random_sk()
|
||||||
nodes = dict(gen_node(key, FlatOverlay(nodes_ids), bytes(genesis_sk.get_g1())) for key in keys)
|
entropy = RecoveryMode.generate_beacon(bytes(genesis_sk), -1).entropy()
|
||||||
|
|
||||||
|
random.seed(a=entropy, version=2)
|
||||||
|
current_leader = random.choice(nodes_ids)
|
||||||
|
|
||||||
|
nodes = dict(gen_node(key, FlatOverlay(current_leader, nodes_ids, entropy), entropy) for key in keys)
|
||||||
genesis_block = None
|
genesis_block = None
|
||||||
overlay = FlatOverlay(nodes_ids)
|
overlay = FlatOverlay(current_leader, nodes_ids, entropy)
|
||||||
overlay.set_entropy(NormalMode.generate_beacon(genesis_sk, -1).entropy())
|
|
||||||
leader: Carnot = nodes[overlay.leader()]
|
leader: Carnot = nodes[overlay.leader()]
|
||||||
for node in nodes.values():
|
for node in nodes.values():
|
||||||
genesis_block = add_genesis_block(node, genesis_sk)
|
genesis_block = add_genesis_block(node, genesis_sk)
|
||||||
@ -135,8 +137,7 @@ def initial_setup(test_case: TestCase, size: int) -> (Dict[Id, Carnot], Carnot,
|
|||||||
)
|
)
|
||||||
proposed_block = leader.propose_block(1, genesis_votes).payload
|
proposed_block = leader.propose_block(1, genesis_votes).payload
|
||||||
test_case.assertIsNotNone(proposed_block)
|
test_case.assertIsNotNone(proposed_block)
|
||||||
overlay = FlatOverlay(nodes_ids)
|
overlay = overlay.advance(genesis_block.beacon.entropy())
|
||||||
overlay.set_entropy(genesis_block.beacon.entropy())
|
|
||||||
return nodes, leader, proposed_block, overlay
|
return nodes, leader, proposed_block, overlay
|
||||||
|
|
||||||
|
|
||||||
@ -151,25 +152,25 @@ class TestBeaconizedCarnot(TestCase):
|
|||||||
nodes, leader, proposed_block, overlay = initial_setup(self, 5)
|
nodes, leader, proposed_block, overlay = initial_setup(self, 5)
|
||||||
|
|
||||||
for view in range(2, 5):
|
for view in range(2, 5):
|
||||||
root_votes, overlay = succeed(nodes, proposed_block)
|
root_votes, overlay = succeed(nodes, proposed_block, overlay)
|
||||||
leader = nodes[overlay.leader()]
|
leader = nodes[overlay.leader()]
|
||||||
proposed_block = leader.propose_block(view, root_votes).payload
|
proposed_block = leader.propose_block(view, root_votes).payload
|
||||||
|
|
||||||
root_votes, overlay = fail(nodes, proposed_block)
|
root_votes, overlay = fail(nodes, proposed_block, overlay)
|
||||||
leader = nodes[overlay.leader()]
|
leader = nodes[overlay.leader()]
|
||||||
proposed_block = leader.propose_block(6, root_votes).payload
|
proposed_block = leader.propose_block(6, root_votes).payload
|
||||||
|
|
||||||
for view in range(7, 8):
|
for view in range(7, 8):
|
||||||
root_votes, overlay = succeed(nodes, proposed_block)
|
root_votes, overlay = succeed(nodes, proposed_block, overlay)
|
||||||
leader = nodes[overlay.leader()]
|
leader = nodes[overlay.leader()]
|
||||||
proposed_block = leader.propose_block(view, root_votes).payload
|
proposed_block = leader.propose_block(view, root_votes).payload
|
||||||
|
|
||||||
root_votes, overlay = fail(nodes, proposed_block)
|
root_votes, overlay = fail(nodes, proposed_block, overlay)
|
||||||
leader = nodes[overlay.leader()]
|
leader = nodes[overlay.leader()]
|
||||||
proposed_block = leader.propose_block(9, root_votes).payload
|
proposed_block = leader.propose_block(9, root_votes).payload
|
||||||
|
|
||||||
for view in range(10, 15):
|
for view in range(10, 15):
|
||||||
root_votes, overlay = succeed(nodes, proposed_block)
|
root_votes, overlay = succeed(nodes, proposed_block, overlay)
|
||||||
leader = nodes[overlay.leader()]
|
leader = nodes[overlay.leader()]
|
||||||
proposed_block = leader.propose_block(view, root_votes).payload
|
proposed_block = leader.propose_block(view, root_votes).payload
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user