Refactor EntropyOverlay and usages

This commit is contained in:
danielsanchezq 2023-05-25 13:16:56 +02:00
parent 9ae2f99b5c
commit 5bfdacc213
3 changed files with 31 additions and 31 deletions

View File

@ -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)

View File

@ -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()

View File

@ -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