async def ensure_same_side_on_dao_fork(self, peer: BasePeer) -> None: """Ensure we're on the same side of the DAO fork as the given peer. In order to do that we have to request the DAO fork block and its parent, but while we wait for that we may receive other messages from the peer, which are returned so that they can be re-added to our subscribers' queues when the peer is finally added to the pool. """ for start_block, vm_class in self.vm_configuration: if not issubclass(vm_class, HomesteadVM): continue elif not vm_class.support_dao_fork: break elif start_block > vm_class.dao_fork_block_number: # VM comes after the fork, so stop checking break start_block = vm_class.dao_fork_block_number - 1 try: headers = await peer.requests.get_block_headers( # type: ignore start_block, max_headers=2, reverse=False, timeout=CHAIN_SPLIT_CHECK_TIMEOUT, ) except (TimeoutError, PeerConnectionLost) as err: raise DAOForkCheckFailure( "Timed out waiting for DAO fork header from {}: {}".format( peer, err)) from err except MalformedMessage as err: raise DAOForkCheckFailure( "Malformed message while doing DAO fork check with {0}: {1}" .format( peer, err, )) from err except ValidationError as err: raise DAOForkCheckFailure( "Invalid header response during DAO fork check: {}".format( err)) from err if len(headers) != 2: raise DAOForkCheckFailure( "Peer %s failed to return DAO fork check headers".format( peer)) else: parent, header = headers try: vm_class.validate_header(header, parent, check_seal=True) except EthValidationError as err: raise DAOForkCheckFailure( "Peer failed DAO fork check validation: {}".format(err))
async def ensure_same_side_on_dao_fork( self, peer: BasePeer ) -> List[Tuple[protocol.Command, protocol._DecodedMsgType]]: """Ensure we're on the same side of the DAO fork as the given peer. In order to do that we have to request the DAO fork block and its parent, but while we wait for that we may receive other messages from the peer, which are returned so that they can be re-added to our subscribers' queues when the peer is finally added to the pool. """ msgs = [] for start_block, vm_class in self.vm_configuration: if not issubclass(vm_class, HomesteadVM): continue elif not vm_class.support_dao_fork: break elif start_block > vm_class.dao_fork_block_number: # VM comes after the fork, so stop checking break start_block = vm_class.dao_fork_block_number - 1 max_headers = 2 reverse = False peer.request_block_headers(start_block, max_headers, reverse) # type: ignore start = time.time() try: while True: elapsed = int(time.time() - start) remaining_timeout = max( 0, CHAIN_SPLIT_CHECK_TIMEOUT - elapsed) cmd, msg = await self.wait(peer.read_msg(), timeout=remaining_timeout) if isinstance(cmd, protocol.BaseBlockHeaders): headers = cmd.extract_headers(msg) break else: msgs.append((cmd, msg)) continue except (TimeoutError, PeerConnectionLost) as e: raise DAOForkCheckFailure( "Timed out waiting for DAO fork header from {}: {}".format( peer, e)) try: validate_header_response(start_block, max_headers, reverse, headers) parent, header = headers vm_class.validate_header(header, parent, check_seal=True) except ValidationError as e: raise DAOForkCheckFailure( "Peer failed DAO fork check validation: {}".format(e)) return msgs
async def ensure_same_side_on_dao_fork( self, peer: BasePeer ) -> List[Tuple[protocol.Command, protocol._DecodedMsgType]]: """Ensure we're on the same side of the DAO fork as the given peer. In order to do that we have to request the DAO fork block and its parent, but while we wait for that we may receive other messages from the peer, which are returned so that they can be re-added to our subscribers' queues when the peer is finally added to the pool. """ from trinity.protocol.base_block_headers import BaseBlockHeaders msgs = [] for start_block, vm_class in self.vm_configuration: if not issubclass(vm_class, HomesteadVM): continue elif not vm_class.support_dao_fork: break elif start_block > vm_class.dao_fork_block_number: # VM comes after the fork, so stop checking break start_block = vm_class.dao_fork_block_number - 1 # TODO: This can be either an `ETHPeer` or an `LESPeer`. Will be # fixed once full awaitable request API is completed. request = peer.request_block_headers( # type: ignore start_block, max_headers=2, reverse=False, ) start = time.time() try: while True: elapsed = int(time.time() - start) remaining_timeout = max( 0, CHAIN_SPLIT_CHECK_TIMEOUT - elapsed) cmd, msg = await self.wait(peer.read_msg(), timeout=remaining_timeout) if isinstance(cmd, BaseBlockHeaders): headers = cmd.extract_headers(msg) break else: msgs.append((cmd, msg)) continue except (TimeoutError, PeerConnectionLost) as err: raise DAOForkCheckFailure( "Timed out waiting for DAO fork header from {}: {}".format( peer, err)) except MalformedMessage as err: raise DAOForkCheckFailure( "Malformed message while doing DAO fork check with {0}: {1}" .format( peer, err, )) from err try: request.validate_headers(headers) except ValidationError as err: raise DAOForkCheckFailure( "Invalid header response during DAO fork check: {}".format( err)) if len(headers) != 2: raise DAOForkCheckFailure( "Peer failed to return all requested headers for DAO fork check" ) else: parent, header = headers try: vm_class.validate_header(header, parent, check_seal=True) except EthValidationError as err: raise DAOForkCheckFailure( "Peer failed DAO fork check validation: {}".format(err)) return msgs