2024-01-29 13:29:56 +00:00
|
|
|
from unittest import TestCase
|
2024-01-31 22:09:03 +00:00
|
|
|
from itertools import repeat
|
2024-01-29 13:29:56 +00:00
|
|
|
import numpy as np
|
|
|
|
import hashlib
|
|
|
|
|
|
|
|
from copy import deepcopy
|
2024-02-01 09:56:49 +00:00
|
|
|
from cryptarchia.cryptarchia import (
|
|
|
|
maxvalid_bg,
|
|
|
|
Chain,
|
|
|
|
BlockHeader,
|
|
|
|
Slot,
|
|
|
|
Id,
|
|
|
|
MockLeaderProof,
|
2024-02-01 10:53:59 +00:00
|
|
|
Coin,
|
2024-02-01 09:56:49 +00:00
|
|
|
)
|
2024-01-29 13:29:56 +00:00
|
|
|
|
2024-03-09 13:34:08 +00:00
|
|
|
from .test_common import mk_chain
|
2024-01-29 13:29:56 +00:00
|
|
|
|
|
|
|
|
2024-03-09 13:34:08 +00:00
|
|
|
class TestForkChoice(TestCase):
|
2024-01-29 13:29:56 +00:00
|
|
|
def test_fork_choice_long_sparse_chain(self):
|
|
|
|
# The longest chain is not dense after the fork
|
2024-03-09 13:34:08 +00:00
|
|
|
short_coin, long_coin = Coin(sk=0, value=100), Coin(sk=1, value=100)
|
|
|
|
common, long_coin = mk_chain(parent=bytes(32), coin=long_coin, slots=range(50))
|
|
|
|
|
|
|
|
long_chain_sparse_ext, long_coin = mk_chain(
|
|
|
|
parent=common[-1].id(), coin=long_coin, slots=range(50, 100, 2)
|
|
|
|
)
|
|
|
|
|
|
|
|
short_chain_dense_ext, _ = mk_chain(
|
|
|
|
parent=common[-1].id(), coin=short_coin, slots=range(50, 100)
|
|
|
|
)
|
2024-01-29 13:29:56 +00:00
|
|
|
|
2024-03-09 13:34:08 +00:00
|
|
|
# add more blocks to the long chain to ensure the long chain is indeed longer
|
|
|
|
long_chain_further_ext, _ = mk_chain(
|
|
|
|
parent=long_chain_sparse_ext[-1].id(), coin=long_coin, slots=range(100, 126)
|
|
|
|
)
|
|
|
|
|
|
|
|
long_chain = deepcopy(common) + long_chain_sparse_ext + long_chain_further_ext
|
|
|
|
short_chain = deepcopy(common) + short_chain_dense_ext
|
2024-01-29 13:29:56 +00:00
|
|
|
assert len(long_chain) > len(short_chain)
|
2024-03-09 13:34:08 +00:00
|
|
|
|
2024-01-29 13:29:56 +00:00
|
|
|
# by setting a low k we trigger the density choice rule
|
|
|
|
k = 1
|
|
|
|
s = 50
|
2024-03-09 13:34:08 +00:00
|
|
|
|
2024-02-09 14:12:12 +00:00
|
|
|
short_chain = Chain(short_chain, genesis=bytes(32))
|
|
|
|
long_chain = Chain(long_chain, genesis=bytes(32))
|
2024-03-09 13:34:08 +00:00
|
|
|
assert maxvalid_bg(short_chain, [long_chain], k, s) == short_chain
|
2024-01-29 13:29:56 +00:00
|
|
|
|
|
|
|
# However, if we set k to the fork length, it will be accepted
|
2024-02-09 14:12:12 +00:00
|
|
|
k = long_chain.length()
|
2024-03-09 13:34:08 +00:00
|
|
|
assert maxvalid_bg(short_chain, [long_chain], k, s) == long_chain
|
2024-01-29 13:29:56 +00:00
|
|
|
|
|
|
|
def test_fork_choice_long_dense_chain(self):
|
|
|
|
# The longest chain is also the densest after the fork
|
2024-03-09 13:34:08 +00:00
|
|
|
short_coin, long_coin = Coin(sk=0, value=100), Coin(sk=1, value=100)
|
|
|
|
common, long_coin = mk_chain(
|
|
|
|
parent=bytes(32), coin=long_coin, slots=range(1, 50)
|
|
|
|
)
|
|
|
|
|
|
|
|
long_chain_dense_ext, _ = mk_chain(
|
|
|
|
parent=common[-1].id(), coin=long_coin, slots=range(50, 100)
|
|
|
|
)
|
|
|
|
short_chain_sparse_ext, _ = mk_chain(
|
|
|
|
parent=common[-1].id(), coin=short_coin, slots=range(50, 100, 2)
|
|
|
|
)
|
|
|
|
|
|
|
|
long_chain = deepcopy(common) + long_chain_dense_ext
|
|
|
|
short_chain = deepcopy(common) + short_chain_sparse_ext
|
|
|
|
|
2024-01-29 13:29:56 +00:00
|
|
|
k = 1
|
|
|
|
s = 50
|
2024-02-09 14:12:12 +00:00
|
|
|
short_chain = Chain(short_chain, genesis=bytes(32))
|
|
|
|
long_chain = Chain(long_chain, genesis=bytes(32))
|
2024-03-09 13:34:08 +00:00
|
|
|
assert maxvalid_bg(short_chain, [long_chain], k, s) == long_chain
|