mirror of
https://github.com/logos-blockchain/logos-blockchain-specs.git
synced 2026-01-08 16:13:10 +00:00
cryptarchia/ghost: common_prefix_depth returns depth of both chains
This commit is contained in:
parent
893ffb5915
commit
37eb040a99
@ -2,7 +2,7 @@ from typing import TypeAlias, List, Optional, Dict
|
||||
from hashlib import sha256, blake2b
|
||||
from math import floor
|
||||
from copy import deepcopy
|
||||
from itertools import chain
|
||||
import itertools
|
||||
import functools
|
||||
from dataclasses import dataclass, field, replace
|
||||
import logging
|
||||
@ -347,7 +347,7 @@ class LedgerState:
|
||||
|
||||
self.nonce = h.digest()
|
||||
self.block = block
|
||||
for proof in chain(block.orphaned_proofs, [block]):
|
||||
for proof in itertools.chain(block.orphaned_proofs, [block]):
|
||||
self.apply_leader_proof(proof.leader_proof)
|
||||
|
||||
def apply_leader_proof(self, proof: MockLeaderProof):
|
||||
@ -722,7 +722,7 @@ class Leader:
|
||||
|
||||
def common_prefix_depth(
|
||||
local_chain: Id, fork: Id, states: Dict[Id, LedgerState]
|
||||
) -> int:
|
||||
) -> (int, int):
|
||||
|
||||
local_block = local_chain
|
||||
fork_block = fork
|
||||
@ -747,7 +747,7 @@ def common_prefix_depth(
|
||||
|
||||
if local_block in seen:
|
||||
# we had seen this block from the fork chain
|
||||
return depth
|
||||
return depth, seen[local_block]
|
||||
|
||||
if local_block in states:
|
||||
seen[local_block] = depth
|
||||
@ -756,7 +756,7 @@ def common_prefix_depth(
|
||||
if fork_block in seen:
|
||||
# we had seen the fork in the local chain
|
||||
# return the depth w.r.t to the local chain
|
||||
return seen[fork_block]
|
||||
return seen[fork_block], depth
|
||||
|
||||
if fork_block in states:
|
||||
seen[fork_block] = depth
|
||||
@ -786,21 +786,26 @@ def maxvalid_bg(
|
||||
k: int,
|
||||
s: int,
|
||||
) -> Chain:
|
||||
# assert type(local_chain) == Id
|
||||
# assert all(type(f) == Id for f in forks)
|
||||
|
||||
cmax = local_chain
|
||||
for chain in forks:
|
||||
m = common_prefix_depth(cmax.tip_id(), chain.tip_id(), states)
|
||||
if m <= k:
|
||||
for fork in forks:
|
||||
local_depth, fork_depth = common_prefix_depth(
|
||||
cmax.tip_id(), fork.tip_id(), states
|
||||
)
|
||||
if local_depth <= k:
|
||||
# Classic longest chain rule with parameter k
|
||||
if cmax.length() < chain.length():
|
||||
cmax = chain
|
||||
if local_depth < fork_depth:
|
||||
cmax = fork
|
||||
else:
|
||||
# The chain is forking too much, we need to pay a bit more attention
|
||||
# In particular, select the chain that is the densest after the fork
|
||||
forking_slot = Slot(cmax.blocks[-m].slot.absolute_slot + s)
|
||||
forking_slot = Slot(cmax.blocks[-local_depth].slot.absolute_slot + s)
|
||||
cmax_density = chain_density(cmax, forking_slot)
|
||||
candidate_density = chain_density(chain, forking_slot)
|
||||
candidate_density = chain_density(fork, forking_slot)
|
||||
if cmax_density < candidate_density:
|
||||
cmax = chain
|
||||
cmax = fork
|
||||
|
||||
return cmax
|
||||
|
||||
|
||||
@ -44,28 +44,28 @@ class TestForkChoice(TestCase):
|
||||
b.id(): LedgerState(block=b) for b in [b0, b1, b2, b3, b4, b5, b6, b7]
|
||||
}
|
||||
|
||||
assert (d := common_prefix_depth(b0.id(), b0.id(), states)) == 0, d
|
||||
assert (d := common_prefix_depth(b1.id(), b0.id(), states)) == 1, d
|
||||
assert (d := common_prefix_depth(b0.id(), b1.id(), states)) == 0, d
|
||||
assert (d := common_prefix_depth(b1.id(), b1.id(), states)) == 0, d
|
||||
assert (d := common_prefix_depth(b2.id(), b0.id(), states)) == 2, d
|
||||
assert (d := common_prefix_depth(b0.id(), b2.id(), states)) == 0, d
|
||||
assert (d := common_prefix_depth(b3.id(), b0.id(), states)) == 3, d
|
||||
assert (d := common_prefix_depth(b0.id(), b3.id(), states)) == 0, d
|
||||
assert (d := common_prefix_depth(b1.id(), b4.id(), states)) == 1, d
|
||||
assert (d := common_prefix_depth(b4.id(), b1.id(), states)) == 1, d
|
||||
assert (d := common_prefix_depth(b1.id(), b5.id(), states)) == 1, d
|
||||
assert (d := common_prefix_depth(b5.id(), b1.id(), states)) == 2, d
|
||||
assert (d := common_prefix_depth(b2.id(), b5.id(), states)) == 2, d
|
||||
assert (d := common_prefix_depth(b5.id(), b2.id(), states)) == 2, d
|
||||
assert (d := common_prefix_depth(b3.id(), b5.id(), states)) == 3, d
|
||||
assert (d := common_prefix_depth(b5.id(), b3.id(), states)) == 2, d
|
||||
assert (d := common_prefix_depth(b3.id(), b6.id(), states)) == 1, d
|
||||
assert (d := common_prefix_depth(b6.id(), b3.id(), states)) == 1, d
|
||||
assert (d := common_prefix_depth(b3.id(), b7.id(), states)) == 1, d
|
||||
assert (d := common_prefix_depth(b7.id(), b3.id(), states)) == 2, d
|
||||
assert (d := common_prefix_depth(b5.id(), b7.id(), states)) == 2, d
|
||||
assert (d := common_prefix_depth(b7.id(), b5.id(), states)) == 4, d
|
||||
assert (d := common_prefix_depth(b0.id(), b0.id(), states)) == (0, 0), d
|
||||
assert (d := common_prefix_depth(b1.id(), b0.id(), states)) == (1, 0), d
|
||||
assert (d := common_prefix_depth(b0.id(), b1.id(), states)) == (0, 1), d
|
||||
assert (d := common_prefix_depth(b1.id(), b1.id(), states)) == (0, 0), d
|
||||
assert (d := common_prefix_depth(b2.id(), b0.id(), states)) == (2, 0), d
|
||||
assert (d := common_prefix_depth(b0.id(), b2.id(), states)) == (0, 2), d
|
||||
assert (d := common_prefix_depth(b3.id(), b0.id(), states)) == (3, 0), d
|
||||
assert (d := common_prefix_depth(b0.id(), b3.id(), states)) == (0, 3), d
|
||||
assert (d := common_prefix_depth(b1.id(), b4.id(), states)) == (1, 1), d
|
||||
assert (d := common_prefix_depth(b4.id(), b1.id(), states)) == (1, 1), d
|
||||
assert (d := common_prefix_depth(b1.id(), b5.id(), states)) == (1, 2), d
|
||||
assert (d := common_prefix_depth(b5.id(), b1.id(), states)) == (2, 1), d
|
||||
assert (d := common_prefix_depth(b2.id(), b5.id(), states)) == (2, 2), d
|
||||
assert (d := common_prefix_depth(b5.id(), b2.id(), states)) == (2, 2), d
|
||||
assert (d := common_prefix_depth(b3.id(), b5.id(), states)) == (3, 2), d
|
||||
assert (d := common_prefix_depth(b5.id(), b3.id(), states)) == (2, 3), d
|
||||
assert (d := common_prefix_depth(b3.id(), b6.id(), states)) == (1, 1), d
|
||||
assert (d := common_prefix_depth(b6.id(), b3.id(), states)) == (1, 1), d
|
||||
assert (d := common_prefix_depth(b3.id(), b7.id(), states)) == (1, 2), d
|
||||
assert (d := common_prefix_depth(b7.id(), b3.id(), states)) == (2, 1), d
|
||||
assert (d := common_prefix_depth(b5.id(), b7.id(), states)) == (2, 4), d
|
||||
assert (d := common_prefix_depth(b7.id(), b5.id(), states)) == (4, 2), d
|
||||
|
||||
def test_fork_choice_long_sparse_chain(self):
|
||||
# The longest chain is not dense after the fork
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user