mirror of
https://github.com/logos-blockchain/logos-blockchain-specs.git
synced 2026-01-07 07:33:09 +00:00
Fix unhappy path double increments
Fill missing qc building implementations
This commit is contained in:
parent
5ad1d7b90f
commit
9496da8ad5
@ -284,7 +284,7 @@ class Carnot:
|
||||
def update_timeout_qc(self, timeout_qc: TimeoutQc):
|
||||
match (self.last_timeout_view_qc, timeout_qc):
|
||||
case (None, timeout_qc):
|
||||
self.local_high_qc = timeout_qc
|
||||
self.last_timeout_view_qc = timeout_qc
|
||||
case (self.last_timeout_view_qc, timeout_qc) if timeout_qc.view > self.last_timeout_view_qc.view:
|
||||
self.last_timeout_view_qc = timeout_qc
|
||||
|
||||
@ -303,11 +303,6 @@ class Carnot:
|
||||
self.update_high_qc(block.qc)
|
||||
self.try_commit_grand_parent(block)
|
||||
|
||||
def receive_timeout_qc(self, timeout_qc: TimeoutQc):
|
||||
# TODO: we should be more strict with views in the sense that we should not accept 'future' events
|
||||
assert timeout_qc.view >= self.current_view
|
||||
self.rebuild_overlay_from_timeout_qc(timeout_qc)
|
||||
|
||||
def approve_block(self, block: Block, votes: Set[Vote]):
|
||||
assert block.id() in self.safe_blocks
|
||||
assert len(votes) == self.overlay.super_majority_threshold(self.id)
|
||||
@ -354,9 +349,16 @@ class Carnot:
|
||||
if self.overlay.is_member_of_root_committee(self.id):
|
||||
self.send(msg, self.overlay.leader(self.current_view + 1))
|
||||
|
||||
def build_qc(self, view: View, block: Block) -> Qc:
|
||||
# TODO: implement unhappy path
|
||||
# Maybe better do build aggregatedQC for unhappy path?
|
||||
def build_qc(self, view: View, block: Optional[Block], new_views: Optional[Set[NewView]]) -> Qc:
|
||||
# unhappy path
|
||||
if new_views:
|
||||
new_views = list(new_views)
|
||||
return AggregateQc(
|
||||
qcs=[msg.high_qc.view for msg in new_views],
|
||||
highest_qc=max(new_views, key=lambda x: x.high_qc.view).high_qc,
|
||||
view=new_views[0].view
|
||||
)
|
||||
# happy path
|
||||
return StandardQc(
|
||||
view=view,
|
||||
block=block.id()
|
||||
@ -364,9 +366,20 @@ class Carnot:
|
||||
|
||||
def propose_block(self, view: View, quorum: Quorum):
|
||||
assert self.overlay.is_leader(self.id)
|
||||
assert len(quorum) >= self.overlay.leader_super_majority_threshold(self.id)
|
||||
vote = list(quorum)[0]
|
||||
qc = self.build_qc(vote.view, self.safe_blocks[vote.block])
|
||||
|
||||
qc = None
|
||||
quorum = list(quorum)
|
||||
# happy path
|
||||
if isinstance(quorum[0], Vote):
|
||||
assert len(quorum) >= self.overlay.leader_super_majority_threshold(self.id)
|
||||
vote = quorum[0]
|
||||
qc = self.build_qc(vote.view, self.safe_blocks[vote.block], None)
|
||||
# unhappy path
|
||||
elif isinstance(quorum[0], NewView):
|
||||
assert len(quorum) >= self.overlay.leader_super_majority_threshold(self.id)
|
||||
new_view = quorum[0]
|
||||
qc = self.build_qc(new_view.view, None, quorum)
|
||||
|
||||
block = Block(
|
||||
view=view,
|
||||
qc=qc,
|
||||
@ -440,7 +453,7 @@ class Carnot:
|
||||
assert self.current_view > max(self.highest_voted_view - 1, self.local_high_qc.view)
|
||||
assert self.overlay.is_member_of_root_committee(self.id)
|
||||
|
||||
timeout_qc = self.build_timeout_qc(msgs)
|
||||
timeout_qc = self.build_timeout_qc(msgs, self.id)
|
||||
self.update_timeout_qc(timeout_qc)
|
||||
self.update_high_qc(timeout_qc.high_qc)
|
||||
# The view failed and the node timeout. The node cannot timeout itself again until it gets updated
|
||||
@ -471,7 +484,6 @@ class Carnot:
|
||||
|
||||
self.update_high_qc(new_high_qc)
|
||||
self.update_timeout_qc(timeout_qc)
|
||||
self.increment_view_timeout_qc(timeout_qc)
|
||||
# The view failed and the node timeout. The node cannot timeout itself again until it gets updated
|
||||
# from a higher qc, either from a TimeoutQc or from a Qc coming from a newer proposed block.
|
||||
# In case the node do not get updated because the received qc is not new enough we need to skip
|
||||
@ -510,7 +522,7 @@ class Carnot:
|
||||
if new_high_qc.view >= self.local_high_qc.view:
|
||||
self.update_high_qc(new_high_qc)
|
||||
self.update_timeout_qc(timeout_qc)
|
||||
self.increment_view_timeout_qc(timeout_qc)
|
||||
|
||||
timeout_msg = NewView(
|
||||
view=self.current_view,
|
||||
high_qc=self.local_high_qc,
|
||||
@ -527,8 +539,15 @@ class Carnot:
|
||||
assert timeout_qc.view >= self.current_view
|
||||
self.overlay = Overlay()
|
||||
|
||||
def build_timeout_qc(self, msgs: Set[Timeout]) -> TimeoutQc:
|
||||
pass
|
||||
def build_timeout_qc(self, msgs: Set[Timeout], sender: Id) -> TimeoutQc:
|
||||
msgs = list(msgs)
|
||||
return TimeoutQc(
|
||||
view=msgs[0].view,
|
||||
high_qc=max(msgs, key=lambda x: x.high_qc.view).high_qc,
|
||||
qc_views=[msg.view for msg in msgs],
|
||||
sender_ids={msg.sender for msg in msgs},
|
||||
sender=sender,
|
||||
)
|
||||
|
||||
def send(self, vote: Vote | Timeout | NewView | TimeoutQc, *ids: Id):
|
||||
pass
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user