def send_get_proofs(self, *proofs: ProofRequest) -> int: payload = GetProofsPayload( request_id=gen_request_id(), proofs=proofs, ) self.protocol.send(self.protocol.get_proofs_command_type(payload)) return payload.request_id
def send_get_block_headers(self, block_number_or_hash: Union[BlockNumber, Hash32], max_headers: int, skip: int, reverse: bool, request_id: int = None) -> int: """Send a GetBlockHeaders msg to the remote. This requests that the remote send us up to max_headers, starting from block_number_or_hash if reverse is False or ending at block_number_or_hash if reverse is True. """ if request_id is None: request_id = gen_request_id() cmd = GetBlockHeaders(self.cmd_id_offset) data = { 'request_id': request_id, 'query': GetBlockHeadersQuery( block_number_or_hash, max_headers, skip, reverse, ), } header, body = cmd.encode(data) self.send(header, body) return request_id
async def __call__( # type: ignore self, block_number_or_hash: BlockIdentifier, max_headers: int = None, skip: int = 0, reverse: bool = True, timeout: float = None) -> Tuple[BlockHeaderAPI, ...]: original_request_args = (block_number_or_hash, max_headers, skip, reverse) validator = GetBlockHeadersValidator(*original_request_args) query = BlockHeadersQuery( block_number_or_hash=block_number_or_hash, max_headers=max_headers, skip=skip, reverse=reverse, ) payload = GetBlockHeadersPayload( request_id=gen_request_id(), query=query, ) request = GetBlockHeaders(payload) return tuple(await self.get_result( request, self._normalizer, validator, match_payload_request_id, timeout, ))
def send_get_contract_codes(self, *code_requests: ContractCodeRequest) -> int: payload = GetContractCodesPayload( request_id=gen_request_id(), code_requests=code_requests, ) self.protocol.send(GetContractCodes(payload)) return payload.request_id
async def coro_get_receipts(self, block_hash: Hash32) -> List[Receipt]: peer = cast(LESPeer, self.peer_pool.highest_td_peer) self.logger.debug("Fetching %s receipts from %s", encode_hex(block_hash), peer) request_id = gen_request_id() peer.sub_proto.send_get_receipts(block_hash, request_id) reply = await self._wait_for_reply(request_id) if not reply['receipts']: raise BlockNotFound(f"No block with hash {block_hash} found") return reply['receipts'][0]
def send_get_receipts(self, block_hash: bytes, request_id: int=None) -> int: if request_id is None: request_id = gen_request_id() data = { 'request_id': request_id, 'block_hashes': [block_hash], } header, body = GetReceipts(self.cmd_id_offset, self.snappy_support).encode(data) self.transport.send(header, body) return request_id
def send_get_contract_code(self, block_hash: bytes, key: bytes, request_id: int=None) -> int: if request_id is None: request_id = gen_request_id() data = { 'request_id': request_id, 'code_requests': [ContractCodeRequest(block_hash, key)], } header, body = GetContractCodes(self.cmd_id_offset, self.snappy_support).encode(data) self.transport.send(header, body) return request_id
def send_get_receipts(self, block_hashes: Sequence[Hash32]) -> int: if len(block_hashes) > MAX_RECEIPTS_FETCH: raise ValidationError( f"Cannot ask for more than {MAX_RECEIPTS_FETCH} receipts in a single request" ) payload = GetReceiptsPayload( request_id=gen_request_id(), block_hashes=tuple(block_hashes), ) self.protocol.send(GetReceipts(payload)) return payload.request_id
def send_get_block_bodies(self, block_hashes: Sequence[Hash32]) -> int: if len(block_hashes) > MAX_BODIES_FETCH: raise ValueError( f"Cannot ask for more than {MAX_BODIES_FETCH} blocks in a single request" ) payload = GetBlockBodiesPayload( request_id=gen_request_id(), block_hashes=tuple(block_hashes), ) self.protocol.send(GetBlockBodies(payload)) return payload.request_id
async def _get_proof(self, peer: LESPeer, block_hash: bytes, account_key: bytes, key: bytes, from_level: int = 0) -> List[bytes]: request_id = gen_request_id() peer.sub_proto.send_get_proof(block_hash, account_key, key, from_level, request_id) reply = await self._wait_for_reply(request_id) return reply['proof']
async def __call__( # type: ignore self, block_hash: Hash32, timeout: float = None) -> Tuple[Hash32, ...]: validator = GetBlockWitnessHashesValidator() request = GetBlockWitnessHashes(GetBlockWitnessHashesPayload(gen_request_id(), block_hash)) result = await self.get_result( request, self._normalizer, validator, match_payload_request_id, timeout, ) return result.node_hashes
def send_block_headers(self, headers: Tuple[BlockHeader, ...], buffer_value: int, request_id: int=None) -> int: req_id = request_id if not None else gen_request_id() self._event_bus.broadcast_nowait( SendBlockHeadersEvent(self.remote, headers, buffer_value, req_id), self._broadcast_config, ) return req_id
async def coro_get_block_body_by_hash(self, block_hash: Hash32) -> BlockBody: peer = cast(LESPeer, self.peer_pool.highest_td_peer) self.logger.debug("Fetching block %s from %s", encode_hex(block_hash), peer) request_id = gen_request_id() peer.sub_proto.send_get_block_bodies([block_hash], request_id) reply = await self._wait_for_reply(request_id) if not reply['bodies']: raise BlockNotFound( f"Peer {peer} has no block with hash {block_hash}") return reply['bodies'][0]
def send_get_proof(self, block_hash: bytes, account_key: bytes, key: bytes, from_level: int, request_id: int=None) -> int: if request_id is None: request_id = gen_request_id() data = { 'request_id': request_id, 'proof_requests': [ProofRequest(block_hash, account_key, key, from_level)], } header, body = GetProofs(self.cmd_id_offset, self.snappy_support).encode(data) self.transport.send(header, body) return request_id
def send_block_headers( self, headers: Tuple[BlockHeader, ...], buffer_value: int, request_id: int=None) -> int: if request_id is None: request_id = gen_request_id() data = { 'request_id': request_id, 'headers': headers, 'buffer_value': buffer_value, } header, body = BlockHeaders(self.cmd_id_offset, self.snappy_support).encode(data) self.transport.send(header, body) return request_id
def send_block_headers(self, headers: Sequence[BlockHeaderAPI], buffer_value: int = 0, request_id: int = None) -> int: if request_id is None: request_id = gen_request_id() payload = BlockHeadersPayload( request_id=request_id, buffer_value=buffer_value, headers=tuple(headers), ) self.protocol.send(BlockHeaders(payload)) return payload.request_id
def _request_block_from_peers(self, block_root: Hash32) -> None: for peer in self._peer_pool.connected_nodes.values(): peer = cast(BCCPeer, peer) request_id = gen_request_id() self.logger.debug( bold_red( f"send block request to: request_id={request_id}, peer={peer}" )) self.map_request_id_block_root[request_id] = block_root peer.sub_proto.send_get_blocks( block_root, max_blocks=1, request_id=request_id, )
def send_get_block_bodies(self, block_hashes: List[bytes], request_id: int=None) -> int: if request_id is None: request_id = gen_request_id() if len(block_hashes) > constants.MAX_BODIES_FETCH: raise ValueError( f"Cannot ask for more than {constants.MAX_BODIES_FETCH} blocks in a single request" ) data = { 'request_id': request_id, 'block_hashes': block_hashes, } header, body = GetBlockBodies(self.cmd_id_offset, self.snappy_support).encode(data) self.transport.send(header, body) return request_id
def send_block_headers(self, headers: Sequence[BlockHeaderAPI], buffer_value: int = 0, request_id: int = None) -> int: if request_id is None: request_id = gen_request_id() command = BlockHeaders(BlockHeadersPayload( request_id=request_id, buffer_value=buffer_value, headers=tuple(headers), )) self._event_bus.broadcast_nowait( SendBlockHeadersEvent(self.session, command), self._broadcast_config, ) return command.payload.request_id
def _request_block_from_peers(self, block_root: Hash32) -> None: for peer in self._peer_pool.connected_nodes.values(): peer = cast(BCCPeer, peer) request_id = gen_request_id() self.logger.debug( bold_red("Send block request with request_id=%s root=%s to peer=%s"), request_id, encode_hex(block_root), peer, ) self.map_request_id_block_root[request_id] = block_root peer.sub_proto.send_get_blocks( block_root, max_blocks=1, request_id=request_id, )
def _broadcast_block(self, block: BaseBeaconBlock, from_peer: BCCPeer = None) -> None: """ Broadcast a block to the peers, except for ``from_peer``. """ for peer in self._peer_pool.connected_nodes.values(): peer = cast(BCCPeer, peer) # skip the peer who send the block to use if from_peer is not None and peer == from_peer: continue request_id = gen_request_id() self.logger.debug( bold_red( f"send block request to: request_id={request_id}, peer={peer}" )) peer.sub_proto.send_new_block(block=block)
async def __call__( self, # type: ignore block_slot_or_hash: Union[SlotNumber, Hash32], max_headers: int = None, timeout: float = None) -> Tuple[BaseBeaconBlock, ...]: validator = BeaconBlocksValidator(block_slot_or_hash, max_headers) request = self.request_class(block_slot_or_hash, max_headers, gen_request_id()) return await self.get_result( request, self._normalizer, validator, match_payload_request_id, timeout, )
def send_get_block_headers(self, block_number_or_hash: Union[BlockNumber, Hash32], max_headers: int, skip: int, reverse: bool) -> int: if max_headers > MAX_HEADERS_FETCH: raise ValidationError( f"Cannot ask for more than {MAX_HEADERS_FETCH} headers in a single request" ) query = BlockHeadersQuery( block_number_or_hash=block_number_or_hash, max_headers=max_headers, skip=skip, reverse=reverse, ) payload = GetBlockHeadersPayload( request_id=gen_request_id(), query=query, ) self.protocol.send(GetBlockHeaders(payload)) return payload.request_id
async def __call__( # type: ignore self, block_number_or_hash: BlockIdentifier, max_headers: int = None, skip: int = 0, reverse: bool = True, timeout: float = None) -> Tuple[BlockHeaderAPI, ...]: original_request_args = (block_number_or_hash, max_headers, skip, reverse) validator = GetBlockHeadersValidator(*original_request_args) command_args = original_request_args + (gen_request_id(),) request = self.request_class(*command_args) # type: ignore return tuple(await self.get_result( request, self._normalizer, validator, match_payload_request_id, timeout, ))
async def _get_contract_code_from_peer(self, block_hash: Hash32, address: Address, code_hash: Hash32, peer: LESPeer) -> bytes: """ A single attempt to get the contract code from the given peer :raise BadLESResponse: if the peer replies with contract code that does not match the account's code hash """ # request contract code request_id = gen_request_id() peer.sub_proto.send_get_contract_code(block_hash, keccak(address), request_id) reply = await self._wait_for_reply(request_id) if not reply['codes']: bytecode = b'' else: bytecode = reply['codes'][0] # validate bytecode against a proven account if code_hash == keccak(bytecode): return bytecode elif bytecode == b'': await self._raise_for_empty_code(block_hash, address, code_hash, peer) # The following is added for mypy linting: raise RuntimeError( "Unreachable, _raise_for_empty_code must raise its own exception" ) else: # a bad-acting peer sent an invalid non-empty bytecode raise BadLESResponse( "Peer %s sent code %s that did not match hash %s in account %s" % ( peer, encode_hex(bytecode), encode_hex(code_hash), encode_hex(address), ))