add fork choice rule
This commit is contained in:
parent
a587e3a164
commit
989e92635e
|
@ -124,8 +124,8 @@ class Follower:
|
||||||
# in that case, just ignore the block
|
# in that case, just ignore the block
|
||||||
|
|
||||||
# Evaluate the fork choice rule and return the block header of the block that should be the head of the chain
|
# Evaluate the fork choice rule and return the block header of the block that should be the head of the chain
|
||||||
def fork_choice(local_chain: Chain, forks: List[Chain]) -> BlockHeader:
|
def fork_choice(local_chain: Chain, forks: List[Chain]) -> Chain:
|
||||||
pass
|
return maxvalid_bg(local_chain, forks)
|
||||||
|
|
||||||
def tip(self) -> BlockHeader:
|
def tip(self) -> BlockHeader:
|
||||||
return self.fork_choice()
|
return self.fork_choice()
|
||||||
|
@ -218,5 +218,35 @@ class Leader:
|
||||||
return BlockHeader(parent=parent.id(), slot=slot)
|
return BlockHeader(parent=parent.id(), slot=slot)
|
||||||
|
|
||||||
|
|
||||||
|
def common_prefix_len(a: Chain, b: Chain) -> int:
|
||||||
|
for i, (x, y) in enumerate(zip(a.blocks, b.blocks)):
|
||||||
|
if x.id() != y.id():
|
||||||
|
return i
|
||||||
|
return min(len(a.blocks), len(b.blocks))
|
||||||
|
|
||||||
|
|
||||||
|
def chain_density(chain: Chain, slot: Slot) -> int:
|
||||||
|
return count(block for block in chain.blocks if block.slot < slot)
|
||||||
|
|
||||||
|
def maxvalid_bg(local_chain: Chain, forks: List[Chain], k: int, s: int) -> Chain:
|
||||||
|
cmax = local_chain
|
||||||
|
for chain in forks:
|
||||||
|
lowest_common_ancestor = common_prefix_len(cmax, chain)
|
||||||
|
m = cmax.length() - lowest_common_ancestor
|
||||||
|
if m <= k:
|
||||||
|
# Classic longest chain rule with parameter k
|
||||||
|
if cmax.length() < chain.length():
|
||||||
|
cmax = chain
|
||||||
|
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 = cmax.blocks[lowest_common_ancestor].slot
|
||||||
|
cmax_density = chain_density(cmax, forking_slot + s)
|
||||||
|
chain_density = chain_density(chain, forking_slot + s)
|
||||||
|
if cmax_density < chain_density:
|
||||||
|
cmax = chain
|
||||||
|
|
||||||
|
return cmax
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
pass
|
pass
|
||||||
|
|
Loading…
Reference in New Issue