network: smarter switch_unwanted_fork_interface
Previously this function would not switch to a different chain if the current chain contained the preferred block. This was not the intended behaviour: if there is a *stronger* chain that *also* contains the preferred block, we should jump to that. Note that with this commit there will now always be a preferred block (defaults to genesis). Previously, it might seem that often there was none, but actually in practice if the user used the GUI context menu to switch servers even once, there was one (usually genesis). Hence, with the old code, if an attacker mined a single header which then got reorged, auto_connect clients which were connected to the attacker's server would never switch servers (jump chains) even without the user explicitly configuring preference for the stale branch.
This commit is contained in:
@@ -646,6 +646,7 @@ class Blockchain(Logger):
|
||||
|
||||
|
||||
def check_header(header: dict) -> Optional[Blockchain]:
|
||||
"""Returns any Blockchain that contains header, or None."""
|
||||
if type(header) is not dict:
|
||||
return None
|
||||
with blockchains_lock: chains = list(blockchains.values())
|
||||
@@ -656,8 +657,20 @@ def check_header(header: dict) -> Optional[Blockchain]:
|
||||
|
||||
|
||||
def can_connect(header: dict) -> Optional[Blockchain]:
|
||||
"""Returns the Blockchain that has a tip that directly links up
|
||||
with header, or None.
|
||||
"""
|
||||
with blockchains_lock: chains = list(blockchains.values())
|
||||
for b in chains:
|
||||
if b.can_connect(header):
|
||||
return b
|
||||
return None
|
||||
|
||||
|
||||
def get_chains_that_contain_header(height: int, header_hash: str) -> Sequence[Blockchain]:
|
||||
"""Returns a list of Blockchains that contain header, best chain first."""
|
||||
with blockchains_lock: chains = list(blockchains.values())
|
||||
chains = [chain for chain in chains
|
||||
if chain.check_hash(height=height, header_hash=header_hash)]
|
||||
chains = sorted(chains, key=lambda x: x.get_chainwork(), reverse=True)
|
||||
return chains
|
||||
|
||||
Reference in New Issue
Block a user