2
2
3
3
from eth_utils import ValidationError
4
4
5
+ from eth .rlp .headers import BlockHeader
5
6
from eth .vm .forks import HomesteadVM
6
7
7
8
from p2p .exceptions import PeerConnectionLost
@@ -42,7 +43,8 @@ async def ensure_same_side_on_dao_fork(self) -> None:
42
43
# VM comes after the fork, so stop checking
43
44
break
44
45
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
46
48
47
49
try :
48
50
headers = await self .peer .requests .get_block_headers ( # type: ignore
@@ -62,13 +64,46 @@ async def ensure_same_side_on_dao_fork(self) -> None:
62
64
) from err
63
65
64
66
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
+ )
68
79
else :
69
80
parent , header = headers
70
81
71
82
try :
72
83
vm_class .validate_header (header , parent , check_seal = True )
73
84
except ValidationError as err :
74
85
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