cryptarchia/ghost: unimported_orphans returns orphans w.r.t. to tip

This commit is contained in:
David Rusu 2024-11-01 09:49:59 +04:00
parent 30bc359a77
commit 363ca76ff6
5 changed files with 19 additions and 20 deletions

View File

@ -274,9 +274,6 @@ class Chain:
def tip(self) -> BlockHeader:
return self.blocks[-1]
def length(self) -> int:
return len(self.blocks)
def block_position(self, block: Id) -> Optional[int]:
for i, b in enumerate(self.blocks):
if b.id() == block:
@ -313,6 +310,7 @@ class LedgerState:
# The number of observed leaders (blocks + orphans), this measurement is
# used in inferring total active stake in the network.
leader_count: int = 0
height: int = 0
def copy(self):
return LedgerState(
@ -350,6 +348,8 @@ class LedgerState:
for proof in itertools.chain(block.orphaned_proofs, [block]):
self.apply_leader_proof(proof.leader_proof)
self.height += 1
def apply_leader_proof(self, proof: MockLeaderProof):
self.nullifiers.add(proof.nullifier)
self.commitments_spend.add(proof.evolved_commitment)
@ -543,16 +543,16 @@ class Follower:
self.forks.append(self.local_chain)
self.local_chain = new_chain
def unimported_orphans(self, tip: Id) -> list[BlockHeader]:
def unimported_orphans(self) -> list[BlockHeader]:
"""
Returns all unimported orphans w.r.t. the given tip's state.
Orphans are returned in the order that they should be imported.
"""
tip_state = self.ledger_state[tip].copy()
tip_state = self.tip_state().copy()
orphans = []
for fork in [self.local_chain, *self.forks]:
if fork.block_position(tip) is not None:
if fork.block_position(tip_state.block.id()) is not None:
# the tip is a member of this fork, it doesn't make sense
# to take orphans from this fork as they are all already "imported"
continue

View File

@ -27,12 +27,11 @@ class TestNode:
parent = self.follower.tip_id()
epoch_state = self.epoch_state(slot)
if leader_proof := self.leader.try_prove_slot_leader(epoch_state, slot, parent):
orphans = self.follower.unimported_orphans(parent)
self.leader.coin = self.leader.coin.evolve()
return BlockHeader(
parent=parent,
slot=slot,
orphaned_proofs=orphans,
orphaned_proofs=self.follower.unimported_orphans(),
leader_proof=leader_proof,
content_size=0,
content_id=bytes(32),

View File

@ -106,7 +106,7 @@ class TestForkChoice(TestCase):
)
# However, if we set k to the fork length, it will be accepted
k = long_chain.length()
k = len(long_chain.blocks)
assert (
maxvalid_bg(short_chain.tip_id(), [long_chain.tip_id()], states, k, s)
== long_chain.tip_id()

View File

@ -28,7 +28,7 @@ class TestLedgerStateUpdate(TestCase):
follower.on_block(block)
# Follower should have accepted the block
assert follower.local_chain.length() == 1
assert follower.tip_state().height == 1
assert follower.tip() == block
# Follower should have updated their ledger state to mark the leader coin as spent
@ -38,7 +38,7 @@ class TestLedgerStateUpdate(TestCase):
follower.on_block(block)
# Follower should *not* have accepted the block
assert follower.local_chain.length() == 1
assert follower.tip_state().height == 1
assert follower.tip() == block
def test_ledger_state_is_properly_updated_on_reorg(self):

View File

@ -44,7 +44,7 @@ class TestOrphanedProofs(TestCase):
assert follower.tip() == b2
assert [f.tip() for f in follower.forks] == [b3]
assert follower.unimported_orphans(follower.tip_id()) == [b3]
assert follower.unimported_orphans() == [b3]
# -- extend with import --
#
@ -59,7 +59,7 @@ class TestOrphanedProofs(TestCase):
assert follower.tip() == b4
assert [f.tip() for f in follower.forks] == [b3]
assert follower.unimported_orphans(follower.tip_id()) == []
assert follower.unimported_orphans() == []
def test_orphan_proof_import_from_long_running_fork(self):
c_a, c_b = Coin(sk=0, value=10), Coin(sk=1, value=10)
@ -90,7 +90,7 @@ class TestOrphanedProofs(TestCase):
assert follower.tip() == b3
assert [f.tip() for f in follower.forks] == [b5]
assert follower.unimported_orphans(follower.tip_id()) == [b4, b5]
assert follower.unimported_orphans() == [b4, b5]
# -- extend b3, importing the fork --
#
@ -136,7 +136,7 @@ class TestOrphanedProofs(TestCase):
assert follower.tip() == b4
assert [f.tip() for f in follower.forks] == [b7]
assert follower.unimported_orphans(follower.tip_id()) == [b5, b6, b7]
assert follower.unimported_orphans() == [b5, b6, b7]
# -- extend b4, importing the forks --
#
@ -154,7 +154,7 @@ class TestOrphanedProofs(TestCase):
assert follower.tip() == b8
assert [f.tip() for f in follower.forks] == [b7]
assert follower.unimported_orphans(follower.tip_id()) == []
assert follower.unimported_orphans() == []
def test_unimported_orphans(self):
# Given the following fork graph:
@ -200,7 +200,7 @@ class TestOrphanedProofs(TestCase):
assert follower.tip() == b3
assert [f.tip() for f in follower.forks] == [b5, b6]
assert follower.unimported_orphans(follower.tip_id()) == [b4, b5, b6]
assert follower.unimported_orphans() == [b4, b5, b6]
b7, c_a = mk_block(b3, 4, c_a, orphaned_proofs=[b4, b5, b6]), c_a.evolve()
@ -250,15 +250,15 @@ class TestOrphanedProofs(TestCase):
follower.on_block(b)
assert follower.tip() == b4
assert follower.unimported_orphans(follower.tip_id()) == [b5]
assert follower.unimported_orphans() == [b5]
for b in [b6, b7]:
follower.on_block(b)
assert follower.tip() == b6
assert follower.unimported_orphans(follower.tip_id()) == [b7]
assert follower.unimported_orphans() == [b7]
follower.on_block(b8)
assert follower.tip() == b8
assert follower.unimported_orphans(follower.tip_id()) == []
assert follower.unimported_orphans() == []