From 155ac242c3829089fe61ccca16ae547890361c76 Mon Sep 17 00:00:00 2001 From: David Rusu Date: Sun, 1 Dec 2024 22:54:19 +0400 Subject: [PATCH] cryptarchia: update tests --- cryptarchia/cryptarchia.py | 30 +---- cryptarchia/test_fork_choice.py | 207 +------------------------------- 2 files changed, 5 insertions(+), 232 deletions(-) diff --git a/cryptarchia/cryptarchia.py b/cryptarchia/cryptarchia.py index a0cb3f0..8404e42 100644 --- a/cryptarchia/cryptarchia.py +++ b/cryptarchia/cryptarchia.py @@ -511,7 +511,7 @@ def unimported_orphans(self) -> list[BlockHeader]: # Evaluate the fork choice rule and return the chain we should be following def fork_choice(self) -> Id: - return ghost_maxvalid_bg( + return maxvalid_bg( self.local_chain, self.forks, k=self.config.k, @@ -722,32 +722,6 @@ def block_children(states: Dict[Id, LedgerState]) -> Dict[Id, set[Id]]: return children -def block_weight(states: Dict[Id, LedgerState]) -> Dict[Id, int]: - children = block_children(states) - - block_weight = {} - - pending = {b for b in states if len(children[b]) == 0} - ready = set() - - while len(pending) > 0: - new_ready = set() - for b in pending: - if children[b] <= ready: - block_weight[b] = 1 + sum(block_weight[c] for c in children[b]) - new_ready.add(b) - - for b in new_ready: - pending.remove(b) - - if states[b].block.parent in states: - pending.add(states[b].block.parent) - - ready.add(b) - - return block_weight - - # Implementation of the Cryptarchia fork choice rule (following Ouroborous Genesis). # The fork choice has two phases: # 1. if the chain is not forking too deeply, we apply the longest chain fork choice rule @@ -765,8 +739,6 @@ def maxvalid_bg( assert type(local_chain) == Id assert all(type(f) == Id for f in forks) - weights = block_weight(states) - cmax = local_chain for fork in forks: cmax_depth, fork_depth = common_prefix_depth(cmax, fork, states) diff --git a/cryptarchia/test_fork_choice.py b/cryptarchia/test_fork_choice.py index 4c1b39b..1a283c5 100644 --- a/cryptarchia/test_fork_choice.py +++ b/cryptarchia/test_fork_choice.py @@ -2,8 +2,7 @@ from copy import deepcopy from cryptarchia.cryptarchia import ( - block_weight, - ghost_maxvalid_bg, + maxvalid_bg, Slot, Coin, Follower, @@ -15,204 +14,6 @@ class TestForkChoice(TestCase): - def test_ghost_fork_choice(self): - # Example from the GHOST paper - # - # 2D - 3F - 4C - 5B - # / - # / 3E - # / / - # 1B - 2C - 3D - 4B - # / \ \ - # 0 \ 3C - # \ \ - # \ 2B - 3B - # \ - # 1A - 2A - 3A - 4A - 5A - 6A - - coin = Coin(sk=1, value=100) - - b0 = mk_genesis_state([]).block - - b1A = mk_block(b0, 1, coin, content=b"b1A") - b2A = mk_block(b1A, 2, coin, content=b"b2A") - b3A = mk_block(b2A, 3, coin, content=b"b3A") - b4A = mk_block(b3A, 4, coin, content=b"b4A") - b5A = mk_block(b4A, 5, coin, content=b"b5A") - b6A = mk_block(b5A, 6, coin, content=b"b6A") - b1B = mk_block(b0, 1, coin, content=b"b1B") - b2B = mk_block(b1B, 2, coin, content=b"b2B") - b3B = mk_block(b2B, 3, coin, content=b"b3B") - b2C = mk_block(b1B, 2, coin, content=b"b2C") - b3C = mk_block(b2C, 3, coin, content=b"b3C") - b2D = mk_block(b1B, 2, coin, content=b"b2D") - b3D = mk_block(b2C, 3, coin, content=b"b3D") - b4B = mk_block(b3D, 4, coin, content=b"b4B") - b3E = mk_block(b2C, 3, coin, content=b"b3E") - b3F = mk_block(b2D, 3, coin, content=b"b3F") - b4C = mk_block(b3F, 4, coin, content=b"b4C") - b5B = mk_block(b4C, 5, coin, content=b"b5B") - - states = { - b.id(): LedgerState(block=b) - for b in [ - b0, - b1A, - b2A, - b3A, - b4A, - b5A, - b6A, - b1B, - b2B, - b3B, - b4B, - b5B, - b2C, - b3C, - b4C, - b2D, - b3D, - b3E, - b3F, - ] - } - - assert (d := common_prefix_depth(b5B.id(), b3E.id(), states)) == (4, 2), d - - k = 100 - s = int(3 * k / 0.05) - tip = ghost_maxvalid_bg( - b5B.id(), [b3E.id(), b4B.id(), b3C.id(), b3B.id(), b6A.id()], k, s, states - ) - assert tip == b4B.id() - - def test_block_weight_paper(self): - # Example from the GHOST paper - # - # 2D - 3F - 4C - 5B - # / - # / 3E - # / / - # 1B - 2C - 3D - 4B - # / \ \ - # 0 \ 3C - # \ \ - # \ 2B - 3B - # \ - # 1A - 2A - 3A - 4A - 5A - 6A - - coin = Coin(sk=1, value=100) - - b0 = mk_genesis_state([]).block - - b1A = mk_block(b0, 1, coin, content=b"b1A") - b2A = mk_block(b1A, 2, coin, content=b"b2A") - b3A = mk_block(b2A, 3, coin, content=b"b3A") - b4A = mk_block(b3A, 4, coin, content=b"b4A") - b5A = mk_block(b4A, 5, coin, content=b"b5A") - b6A = mk_block(b5A, 6, coin, content=b"b6A") - b1B = mk_block(b0, 1, coin, content=b"b1B") - b2B = mk_block(b1B, 2, coin, content=b"b2B") - b3B = mk_block(b2B, 3, coin, content=b"b3B") - b2C = mk_block(b1B, 2, coin, content=b"b2C") - b3C = mk_block(b2C, 3, coin, content=b"b3C") - b2D = mk_block(b1B, 2, coin, content=b"b2D") - b3D = mk_block(b2C, 3, coin, content=b"b3D") - b4B = mk_block(b3D, 4, coin, content=b"b4B") - b3E = mk_block(b2C, 3, coin, content=b"b3E") - b3F = mk_block(b2D, 3, coin, content=b"b3F") - b4C = mk_block(b3F, 4, coin, content=b"b4C") - b5B = mk_block(b4C, 5, coin, content=b"b5B") - - states = { - b.id(): LedgerState(block=b) - for b in [ - b0, - b1A, - b2A, - b3A, - b4A, - b5A, - b6A, - b1B, - b2B, - b3B, - b4B, - b5B, - b2C, - b3C, - b4C, - b2D, - b3D, - b3E, - b3F, - ] - } - - weight = block_weight(states) - - expected_weight = { - b0.id(): 19, - b1A.id(): 6, - b2A.id(): 5, - b3A.id(): 4, - b4A.id(): 3, - b5A.id(): 2, - b6A.id(): 1, - b1B.id(): 12, - b2B.id(): 2, - b3B.id(): 1, - b4B.id(): 1, - b5B.id(): 1, - b2C.id(): 5, - b3C.id(): 1, - b4C.id(): 2, - b2D.id(): 4, - b3D.id(): 2, - b3E.id(): 1, - b3F.id(): 3, - } - - assert weight == expected_weight - - def test_block_weight(self): - # 6 - 7 - # / - # 0 - 1 - 2 - 3 - # \ - # 4 - 5 - - coin = Coin(sk=1, value=100) - - b0 = mk_genesis_state([]).block - b1 = mk_block(b0, 1, coin) - b2 = mk_block(b1, 2, coin) - b3 = mk_block(b2, 3, coin) - b4 = mk_block(b0, 1, coin, content=b"b4") - b5 = mk_block(b4, 2, coin) - b6 = mk_block(b2, 3, coin, content=b"b6") - b7 = mk_block(b6, 4, coin) - - states = { - b.id(): LedgerState(block=b) for b in [b0, b1, b2, b3, b4, b5, b6, b7] - } - - weights = block_weight(states) - - expected_weights = { - b0.id(): 8, - b1.id(): 5, - b2.id(): 4, - b3.id(): 1, - b4.id(): 2, - b5.id(): 1, - b6.id(): 2, - b7.id(): 1, - } - - assert weights == expected_weights, weights - def test_common_prefix_depth(self): # 6 - 7 # / @@ -289,14 +90,14 @@ def test_fork_choice_long_sparse_chain(self): states = {b.id(): LedgerState(block=b) for b in short_chain + long_chain} assert ( - ghost_maxvalid_bg(short_chain[-1].id(), [long_chain[-1].id()], k, s, states) + maxvalid_bg(short_chain[-1].id(), [long_chain[-1].id()], k, s, states) == short_chain[-1].id() ) # However, if we set k to the fork length, it will be accepted k = len(long_chain) assert ( - ghost_maxvalid_bg(short_chain[-1].id(), [long_chain[-1].id()], k, s, states) + maxvalid_bg(short_chain[-1].id(), [long_chain[-1].id()], k, s, states) == long_chain[-1].id() ) @@ -324,7 +125,7 @@ def test_fork_choice_long_dense_chain(self): states = {b.id(): LedgerState(block=b) for b in short_chain + long_chain} assert ( - ghost_maxvalid_bg(short_chain[-1].id(), [long_chain[-1].id()], k, s, states) + maxvalid_bg(short_chain[-1].id(), [long_chain[-1].id()], k, s, states) == long_chain[-1].id() )