async def get_block_by_hash(self, block_hash: bytes) -> BaseBlock: peer = await self.get_best_peer() try: header = self.chaindb.get_block_header_by_hash(block_hash) except BlockNotFound: self.logger.debug("Fetching header %s from %s", encode_hex(block_hash), peer) request_id = gen_request_id() max_headers = 1 peer.les_proto.send_get_block_headers(block_hash, max_headers, request_id) reply = await peer.wait_for_reply(request_id) if len(reply['headers']) == 0: raise BlockNotFound("Peer {} has no block with hash {}".format(peer, block_hash)) header = reply['headers'][0] self.logger.debug("Fetching block %s from %s", encode_hex(block_hash), peer) request_id = gen_request_id() peer.les_proto.send_get_block_bodies([block_hash], request_id) reply = await peer.wait_for_reply(request_id) if len(reply['bodies']) == 0: raise BlockNotFound("Peer {} has no block with hash {}".format(peer, block_hash)) body = reply['bodies'][0] block_class = self.get_vm_class_for_block_number(header.block_number).get_block_class() transactions = [ block_class.transaction_class.from_base_transaction(tx) for tx in body.transactions ] return block_class( header=header, transactions=transactions, uncles=body.uncles, )
async def get_contract_code(self, block_hash: bytes, key: bytes) -> 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) if not reply['codes']: return b'' return reply['codes'][0]
async def _get_proof(self, block_hash: bytes, account_key: bytes, key: bytes, from_level: int = 0) -> List[bytes]: peer = await self.get_best_peer() request_id = gen_request_id() peer.les_proto.send_get_proof(block_hash, account_key, key, from_level, request_id) reply = await peer.wait_for_reply(request_id) return reply['proof']
async def get_receipts(self, block_hash: bytes) -> 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) if not reply['receipts']: raise BlockNotFound("No block with hash {} found".format(block_hash)) return reply['receipts'][0]
async def get_block_by_hash(self, block_hash: bytes) -> 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) if not reply['bodies']: raise BlockNotFound("Peer {} has no block with hash {}".format(self, block_hash)) return reply['bodies'][0]
async def get_contract_code(self, block_hash: bytes, key: bytes) -> bytes: peer = await self.get_best_peer() request_id = gen_request_id() peer.les_proto.send_get_contract_code(block_hash, key, request_id) reply = await peer.wait_for_reply(request_id) if len(reply['codes']) == 0: return b'' return reply['codes'][0]
async def get_block_header_by_hash(self, block_hash: bytes) -> 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) if not reply['headers']: raise BlockNotFound("Peer {} has no block with hash {}".format(self, block_hash)) return reply['headers'][0]
async def get_receipts(self, block_hash: bytes) -> List[Receipt]: peer = await self.get_best_peer() self.logger.debug("Fetching %s receipts from %s", encode_hex(block_hash), peer) request_id = gen_request_id() peer.les_proto.send_get_receipts(block_hash, request_id) reply = await peer.wait_for_reply(request_id) if len(reply['receipts']) == 0: raise BlockNotFound("No block with hash {} found".format(block_hash)) return reply['receipts'][0]
async def _get_proof(self, 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) return reply['proof']
async def get_proof(self, block_hash: bytes, key: bytes, key2: bytes = b'', from_level: int = 0) -> List[Any]: peer = await self.get_best_peer() request_id = gen_request_id() peer.les_proto.send_get_proof(block_hash, key, key2, from_level, request_id) reply = await peer.wait_for_reply(request_id) if len(reply['nodes']) == 0: return [] return reply['nodes'][0]
async def fetch_headers_starting_at(self, start_block: int) -> 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) 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']
async def get_block_by_hash(self, block_hash: bytes) -> BaseBlock: peer = await self.get_best_peer() self.logger.debug("Fetching block %s from %s", encode_hex(block_hash), peer) request_id = gen_request_id() peer.les_proto.send_get_block_bodies([block_hash], request_id) reply = await peer.wait_for_reply(request_id) if len(reply['bodies']) == 0: raise BlockNotFound("No block with hash {} found".format(block_hash)) body = reply['bodies'][0] # This will raise a BlockNotFound if we don't have the header in our DB, which is correct # because it means our peer doesn't know about it. header = self.chaindb.get_block_header_by_hash(block_hash) block_class = self.get_vm_class_for_block_number(header.block_number).get_block_class() return block_class( header=header, transactions=body.transactions, uncles=body.uncles, chaindb=self.chaindb, )