Пример #1
0
 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
Пример #2
0
    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
Пример #3
0
    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,
        ))
Пример #4
0
 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
Пример #5
0
 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]
Пример #6
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
Пример #7
0
    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
Пример #8
0
 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
Пример #9
0
 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
Пример #10
0
 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']
Пример #11
0
 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
Пример #12
0
    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
Пример #13
0
 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]
Пример #14
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
Пример #15
0
    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
Пример #16
0
 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
Пример #17
0
 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,
         )
Пример #18
0
    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
Пример #19
0
 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
Пример #20
0
    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,
            )
Пример #21
0
 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)
Пример #22
0
    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,
        )
Пример #23
0
 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
Пример #24
0
    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,
        ))
Пример #25
0
    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),
                ))