Пример #1
0
 async def get_receipts(self, block_hash: bytes, cancel_token: CancelToken) -> List[Receipt]:
     request_id = gen_request_id()
     self.sub_proto.send_get_receipts(block_hash, request_id)
     reply = await self._wait_for_reply(request_id, cancel_token)
     if not reply['receipts']:
         raise BlockNotFound("No block with hash {} found".format(block_hash))
     return reply['receipts'][0]
Пример #2
0
 async def get_receipts(self, block_hash: bytes, cancel_token: CancelToken) -> List[Receipt]:
     request_id = gen_request_id()
     self.sub_proto.send_get_receipts(block_hash, request_id)
     reply = await self._wait_for_reply(request_id, cancel_token)
     if not reply['receipts']:
         raise BlockNotFound("No block with hash {} found".format(block_hash))
     return reply['receipts'][0]
Пример #3
0
 def request_block_headers(self,
                           block_number_or_hash: Union[int, bytes],
                           max_headers: int,
                           reverse: bool = True) -> None:
     request_id = gen_request_id()
     self.sub_proto.send_get_block_headers(block_number_or_hash,
                                           max_headers, request_id, reverse)
Пример #4
0
 async def _get_headers_at_chain_split(
         self,
         block_number: BlockNumber) -> Tuple[BlockHeader, BlockHeader]:
     start_block = block_number - 1
     max_headers = 2
     reverse = False
     request_id = gen_request_id()
     self.sub_proto.send_get_block_headers(start_block, max_headers,
                                           request_id, reverse)
     while True:
         cmd, msg = await self.read_msg()
         msg = cast(Dict[str, Any], msg)
         if not isinstance(cmd, les.BlockHeaders):
             self.logger.debug(
                 "Ignoring %s msg from %s as we haven't performed the chain-split check yet",
                 cmd, self)
             continue
         elif msg['request_id'] != request_id:
             self.logger.debug(
                 "Got a BlockHeaders msg with the wrong request_id (%d) from %s, ignoring",
                 msg['request_id'], self)
             continue
         headers = msg['headers']
         validate_header_response(start_block, max_headers, reverse,
                                  headers)
         parent, header = headers
         return header, parent
Пример #5
0
 async def get_block_by_hash(
         self, block_hash: bytes, cancel_token: CancelToken) -> les.LESBlockBody:
     request_id = gen_request_id()
     self.sub_proto.send_get_block_bodies([block_hash], request_id)
     reply = await self._wait_for_reply(request_id, cancel_token)
     if not reply['bodies']:
         raise BlockNotFound("Peer {} has no block with hash {}".format(self, block_hash))
     return reply['bodies'][0]
Пример #6
0
 async def get_contract_code(
         self, block_hash: bytes, key: bytes, cancel_token: CancelToken) -> bytes:
     request_id = gen_request_id()
     self.sub_proto.send_get_contract_code(block_hash, key, request_id)
     reply = await self._wait_for_reply(request_id, cancel_token)
     if not reply['codes']:
         return b''
     return reply['codes'][0]
Пример #7
0
 async def get_contract_code(
         self, block_hash: bytes, key: bytes, cancel_token: CancelToken) -> bytes:
     request_id = gen_request_id()
     self.sub_proto.send_get_contract_code(block_hash, key, request_id)
     reply = await self._wait_for_reply(request_id, cancel_token)
     if not reply['codes']:
         return b''
     return reply['codes'][0]
Пример #8
0
 async def get_contract_code(self, block_hash: Hash32, key: bytes) -> bytes:
     peer = cast(LESPeer, self.peer_pool.highest_td_peer)
     request_id = gen_request_id()
     peer.sub_proto.send_get_contract_code(block_hash, key, request_id)
     reply = await self._wait_for_reply(request_id)
     if not reply['codes']:
         return b''
     return reply['codes'][0]
Пример #9
0
 async def get_contract_code(self, block_hash: Hash32, key: bytes) -> bytes:
     peer = await self.get_best_peer()
     request_id = gen_request_id()
     peer.sub_proto.send_get_contract_code(block_hash, key, request_id)
     reply = await self._wait_for_reply(request_id)
     if not reply['codes']:
         return b''
     return reply['codes'][0]
Пример #10
0
 async def get_block_by_hash(
         self, block_hash: bytes, cancel_token: CancelToken) -> BlockBody:
     request_id = gen_request_id()
     self.sub_proto.send_get_block_bodies([block_hash], request_id)
     reply = await self._wait_for_reply(request_id, cancel_token)
     if not reply['bodies']:
         raise BlockNotFound("Peer {} has no block with hash {}".format(self, block_hash))
     return reply['bodies'][0]
Пример #11
0
 async def get_block_header_by_hash(
         self, block_hash: bytes, cancel_token: CancelToken) -> BlockHeader:
     request_id = gen_request_id()
     max_headers = 1
     self.sub_proto.send_get_block_headers(block_hash, max_headers, request_id)
     reply = await self._wait_for_reply(request_id, cancel_token)
     if not reply['headers']:
         raise BlockNotFound("Peer {} has no block with hash {}".format(self, block_hash))
     return reply['headers'][0]
Пример #12
0
 async def 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("No block with hash {} found".format(block_hash))
     return reply['receipts'][0]
Пример #13
0
 async def 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("Peer {} has no block with hash {}".format(peer, block_hash))
     return reply['bodies'][0]
Пример #14
0
 async def get_block_header_by_hash(
         self, block_hash: bytes, cancel_token: CancelToken) -> BlockHeader:
     request_id = gen_request_id()
     max_headers = 1
     self.sub_proto.send_get_block_headers(block_hash, max_headers, request_id)
     reply = await self._wait_for_reply(request_id, cancel_token)
     if not reply['headers']:
         raise BlockNotFound("Peer {} has no block with hash {}".format(self, block_hash))
     return reply['headers'][0]
Пример #15
0
 async def _get_proof(self,
                      cancel_token: CancelToken,
                      block_hash: bytes,
                      account_key: bytes,
                      key: bytes,
                      from_level: int = 0) -> List[bytes]:
     request_id = gen_request_id()
     self.sub_proto.send_get_proof(block_hash, account_key, key, from_level, request_id)
     reply = await self._wait_for_reply(request_id, cancel_token)
     return reply['proof']
Пример #16
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']
Пример #17
0
 async def _get_proof(self,
                      cancel_token: CancelToken,
                      block_hash: bytes,
                      account_key: bytes,
                      key: bytes,
                      from_level: int = 0) -> List[bytes]:
     request_id = gen_request_id()
     self.sub_proto.send_get_proof(block_hash, account_key, key, from_level, request_id)
     reply = await self._wait_for_reply(request_id, cancel_token)
     return reply['proof']
Пример #18
0
 async def _handle_new_collation_hashes(self, peer, msg):
     """Request those collations."""
     # Request all collations for now, no matter if we now about them or not, as there's no way
     # to header existence at the moment. In the future we won't transfer collations anyway but
     # only collation bodies (headers are retrieved from the main chain), so there's no need to
     # add this at the moment.
     collation_hashes = set(
         collation_hash for collation_hash, _ in msg["collation_hashes_and_periods"]
     )
     if collation_hashes:
         peer.sub_proto.send_get_collations(gen_request_id(), list(collation_hashes))
Пример #19
0
 async def _get_block_header_by_hash(self, peer: LESPeer, block_hash: Hash32) -> BlockHeader:
     self.logger.debug("Fetching header %s from %s", encode_hex(block_hash), peer)
     request_id = gen_request_id()
     max_headers = 1
     peer.sub_proto.send_get_block_headers(block_hash, max_headers, request_id)
     reply = await self._wait_for_reply(request_id)
     if not reply['headers']:
         raise HeaderNotFound("Peer {} has no block with hash {}".format(peer, block_hash))
     header = reply['headers'][0]
     if header.hash != block_hash:
         raise BadLESResponse(
             "Received header hash (%s) does not match what we requested (%s)",
             header.hex_hash, encode_hex(block_hash))
     return header
Пример #20
0
    async def fetch_headers_starting_at(
            self, start_block: int, cancel_token: CancelToken) -> List[BlockHeader]:
        """Fetches up to self.max_headers_fetch starting at start_block.

        Returns a list containing those headers in ascending order of block number.
        """
        request_id = gen_request_id()
        self.sub_proto.send_get_block_headers(
            start_block, self.max_headers_fetch, request_id, reverse=False)
        reply = await self._wait_for_reply(request_id, cancel_token)
        if not reply['headers']:
            raise EmptyGetBlockHeadersReply(
                "No headers in reply. start_block=={}".format(start_block))
        self.logger.info(
            "fetched headers from %s to %s", reply['headers'][0].block_number,
            reply['headers'][-1].block_number)
        return reply['headers']
Пример #21
0
    async def fetch_headers_starting_at(
            self, start_block: int, cancel_token: CancelToken) -> List[BlockHeader]:
        """Fetches up to self.max_headers_fetch starting at start_block.

        Returns a list containing those headers in ascending order of block number.
        """
        request_id = gen_request_id()
        self.sub_proto.send_get_block_headers(
            start_block, self.max_headers_fetch, request_id, reverse=False)
        reply = await self._wait_for_reply(request_id, cancel_token)
        if not reply['headers']:
            raise EmptyGetBlockHeadersReply(
                "No headers in reply. start_block=={}".format(start_block))
        self.logger.info(
            "fetched headers from %s to %s", reply['headers'][0].block_number,
            reply['headers'][-1].block_number)
        return reply['headers']
Пример #22
0
    async def _fetch_headers_starting_at(
            self, peer: LESPeer, start_block: int) -> List[BlockHeader]:
        """Fetches up to self.max_headers_fetch starting at start_block.

        :return: a list containing those headers in ascending order of block number.

        :raise EmptyGetBlockHeadersReply: if no headers are returned
        """
        request_id = gen_request_id()
        peer.sub_proto.send_get_block_headers(
            start_block, peer.max_headers_fetch, request_id, reverse=False)
        reply = await self._wait_for_reply(request_id)
        if not reply['headers']:
            raise EmptyGetBlockHeadersReply(
                "No headers in reply. start_block=={}".format(start_block))
        self.logger.debug(
            "fetched headers from %s to %s", reply['headers'][0].block_number,
            reply['headers'][-1].block_number)
        return reply['headers']
Пример #23
0
    async def get_collations(self, collation_hashes: List[Hash32],
                             cancel_token: CancelToken) -> Set[Collation]:
        # Don't send empty request
        if len(collation_hashes) == 0:
            return set()

        request_id = gen_request_id()
        pending_reply: asyncio.Future[Tuple[
            Command, protocol._DecodedMsgType]] = asyncio.Future()
        self._pending_replies[request_id] = pending_reply
        cast(ShardingProtocol,
             self.sub_proto).send_get_collations(request_id, collation_hashes)
        cmd, msg = await wait_with_token(pending_reply, token=cancel_token)

        if not isinstance(cmd, Collations):
            raise UnexpectedMessage(
                "Expected Collations as response to GetCollations, but got %s",
                cmd.__class__.__name__)
        return set(msg["collations"])
Пример #24
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),
                ))