22
33from eth_utils import ValidationError
44
5+ from eth .rlp .headers import BlockHeader
56from eth .vm .forks import HomesteadVM
67
78from p2p .exceptions import PeerConnectionLost
@@ -42,7 +43,8 @@ async def ensure_same_side_on_dao_fork(self) -> None:
4243 # VM comes after the fork, so stop checking
4344 break
4445
45- start_block = vm_class .get_dao_fork_block_number () - 1
46+ dao_fork_num = vm_class .get_dao_fork_block_number ()
47+ start_block = dao_fork_num - 1
4648
4749 try :
4850 headers = await self .peer .requests .get_block_headers ( # type: ignore
@@ -62,13 +64,46 @@ async def ensure_same_side_on_dao_fork(self) -> None:
6264 ) from err
6365
6466 if len (headers ) != 2 :
65- raise DAOForkCheckFailure (
66- f"{ self .peer } failed to return DAO fork check headers"
67- )
67+ tip_header = await self ._get_tip_header ()
68+ if tip_header .block_number < dao_fork_num :
69+ self .logger .debug (
70+ f"{ self .peer } has tip { tip_header !r} , and returned { headers !r} "
71+ "at DAO fork #{dao_fork_num}. Peer seems to be syncing..."
72+ )
73+ return
74+ else :
75+ raise DAOForkCheckFailure (
76+ f"{ self .peer } has tip { tip_header !r} , but only returned { headers !r} "
77+ "at DAO fork #{dao_fork_num}. Peer seems to be witholding DAO headers..."
78+ )
6879 else :
6980 parent , header = headers
7081
7182 try :
7283 vm_class .validate_header (header , parent , check_seal = True )
7384 except ValidationError as err :
7485 raise DAOForkCheckFailure (f"{ self .peer } failed DAO fork check validation: { err } " )
86+
87+ async def _get_tip_header (self ) -> BlockHeader :
88+ try :
89+ headers = await self .peer .requests .get_block_headers ( # type: ignore
90+ self .peer .head_hash ,
91+ max_headers = 1 ,
92+ timeout = CHAIN_SPLIT_CHECK_TIMEOUT ,
93+ )
94+
95+ except (TimeoutError , PeerConnectionLost ) as err :
96+ raise DAOForkCheckFailure (
97+ f"Timed out waiting for tip header from { self .peer } : { err } "
98+ ) from err
99+ except ValidationError as err :
100+ raise DAOForkCheckFailure (
101+ f"Invalid header response for tip header during DAO fork check: { err } "
102+ ) from err
103+ else :
104+ if len (headers ) != 1 :
105+ raise DAOForkCheckFailure (
106+ f"{ self .peer } returned { headers !r} when asked for tip"
107+ )
108+ else :
109+ return headers [0 ]
0 commit comments