async def handle_stream(self, stream): async for event in stream: if event.WhichOneof('Type') in ('block', 'filtered_block'): self.connected = True if event.WhichOneof('Type') == 'block': block = BlockDecoder().decode( event.block.SerializeToString()) self._last_seen = block['header']['number'] else: block = FilteredBlockDecoder().decode( event.filtered_block.SerializeToString()) self._last_seen = block['number'] self._processBlockEvents(block) self._processTxEvents(block) self._processChaincodeEvents(block) self.check_replay_end() elif event.WhichOneof('Type') == 'status': if event.status == Status.Value('SUCCESS'): # last block if self._ending_block_seen: _logger.debug(f'status received after last block ' f'seen: {event.status}, block-num:' f' {self._last_seen}') if self._ending_block_newest: self.disconnect() else: self.disconnect() else: _logger.error(f'ChannelEventHub has received a unknown' f' message type {event.WhichOneof("Type")}')
def query_block_by_txid(self, requestor, channel_name, peer_names, tx_id, timeout=5): """ Queries block by tx id :param requestor: User role who issue the request :param channel_name: Name of channel to query :param peer_names: Names of the peers to install :param tx_id: Transaction ID :return: A `BlockDecoder` """ peers = [] for peer_name in peer_names: peer = self.get_peer(peer_name) peers.append(peer) channel = self.get_channel(channel_name) tx_context = create_tx_context(requestor, ecies(), TXProposalRequest()) response = channel.query_block_by_txid(tx_context, peers, tx_id) queue = Queue(1) response.subscribe(on_next=lambda x: queue.put(x), on_error=lambda x: queue.put(x)) try: res = queue.get(timeout=timeout) _logger.debug(res) response = res[0][0][0] if response.response: _logger.debug('response status {}'.format( response.response.status)) block = BlockDecoder().decode(response.response.payload) _logger.debug('looking at block {}'.format( block['header']['number'])) return block return response except Exception: _logger.error("Failed to query block: {}", sys.exc_info()[0]) raise
def test_query_block_success(self): loop = asyncio.get_event_loop() loop.run_until_complete(self.invoke_chaincode()) orgs = ["org1.example.com"] for org in orgs: org_admin = self.client.get_user(org, "Admin") channel = self.client.get_channel(self.channel_name) tx_context = create_tx_context(org_admin, org_admin.cryptoSuite, TXProposalRequest()) responses, p, h = channel.query_block(tx_context, [self.peer], '1') res = loop.run_until_complete(asyncio.gather(*responses)) self.assertTrue(all([x.response.status == 200 for x in res])) blocks = [BlockDecoder().decode(v.response.payload) for v in res] self.assertEqual(blocks[0]['header']['number'], 1)
async def handle_stream(self, stream): async for event in stream: self.connected = True if self._filtered: block = FilteredBlockDecoder().decode( event.filtered_block.SerializeToString()) self._last_seen = block['number'] else: block = BlockDecoder().decode(event.block.SerializeToString()) self._last_seen = block['header']['number'] self._processBlockEvents(block) self._processTxEvents(block) self._processChaincodeEvents(block) # if nothing to handle return true # TODO handle empty block (last one) if not self.have_registrations(): return True
def query_transaction(self, requestor, channel_name, peer_names, tx_id, timeout=5): """ Queries block by number :param requestor: User role who issue the request :param channel_name: name of channel to query :param peer_names: Names of the peers to install :param tx_id: The id of the transaction :return: A `BlockDecoder` """ peers = [] for peer_name in peer_names: peer = self.get_peer(peer_name) peers.append(peer) channel = self.get_channel(channel_name) tx_context = create_tx_context(requestor, ecies(), TXProposalRequest()) response = channel.query_transaction(tx_context, peers, tx_id) queue = Queue(1) response.subscribe( on_next=lambda x: queue.put(x), on_error=lambda x: queue.put(x) ) try: res = queue.get(timeout=timeout) response = res[0][0][0] if response.response: logging.debug('response status {}'.format( response.response.status)) process_trans = BlockDecoder().decode_transaction( response.response.payload) return process_trans return response except Exception: logging.error( "Failed to query block: {}", sys.exc_info()[0]) raise
def query_transaction(self, requestor, channel_name, peer_names, tx_id, decode=True): """ Queries block by number :param requestor: User role who issue the request :param channel_name: name of channel to query :param peer_names: Names of the peers to install :param tx_id: The id of the transaction :param deocode: Decode the response payload :return: A `BlockDecoder` or `ProposalResponse` """ peers = [] for peer_name in peer_names: peer = self.get_peer(peer_name) peers.append(peer) channel = self.get_channel(channel_name) tx_context = create_tx_context(requestor, ecies(), TXProposalRequest()) responses = channel.query_transaction(tx_context, peers, tx_id) try: if responses[0][0].response and decode: _logger.debug('response status {}'.format( responses[0][0].response.status)) process_trans = BlockDecoder().decode_transaction( responses[0][0].response.payload) return process_trans return responses[0][0] except Exception: _logger.error("Failed to query block: {}", sys.exc_info()[0]) raise
def query_block(self, requestor, channel_name, peer_names, block_number, decode=True): """ Queries block by number :param requestor: User role who issue the request :param channel_name: name of channel to query :param peer_names: Names of the peers to install :param block_number: Number of a block :param deocode: Decode the response payload :return: A `BlockDecoder` or `ProposalResponse` """ peers = [] for peer_name in peer_names: peer = self.get_peer(peer_name) peers.append(peer) channel = self.get_channel(channel_name) tx_context = create_tx_context(requestor, ecies(), TXProposalRequest()) responses = channel.query_block(tx_context, peers, block_number) try: if responses[0][0].response and decode: _logger.debug('response status {}'.format( responses[0][0].response.status)) block = BlockDecoder().decode(responses[0][0].response.payload) _logger.debug('looking at block {}'.format( block['header']['number'])) return block return responses[0][0] except Exception: _logger.error("Failed to query block: {}", sys.exc_info()[0]) raise
async def get_channel_config_with_orderer(self, tx_context, orderer): """Query the current config block for this channel Args: tx_context: tx_context instance peers: peers in the channel Returns: :class:`ChaincodeQueryResponse` channelinfo with height, currently the only useful information. """ seek_info = create_seek_info() kwargs = {} if orderer._client_cert_path: with open(orderer._client_cert_path, 'rb') as f: b64der = pem_to_der(f.read()) kwargs['tls_cert_hash'] = sha256(b64der).digest() seek_info_header = build_channel_header( common_pb2.HeaderType.Value('DELIVER_SEEK_INFO'), tx_context.tx_id, self.name, current_timestamp(), tx_context.epoch, **kwargs) seek_header = build_header(tx_context.identity, seek_info_header, tx_context.nonce) seek_payload_bytes = create_seek_payload(seek_header, seek_info) sig = tx_context.sign(seek_payload_bytes) envelope = create_envelope(sig, seek_payload_bytes) # this is a stream response block = None stream = orderer.delivery(envelope) async for v in stream: if v.block is None or v.block == '': msg = "fail to get block" _logger.error(msg) raise Exception(msg) block = v.block break block = BlockDecoder().decode(block.SerializeToString()) last_config = block['metadata']['metadata'][common_pb2.LAST_CONFIG] # if nor first block if 'index' in last_config['value']: seek_info = create_seek_info(last_config['value']['index'], last_config['value']['index']) seek_payload_bytes = create_seek_payload(seek_header, seek_info) sig = tx_context.sign(seek_payload_bytes) envelope = create_envelope(sig, seek_payload_bytes) block = None stream = orderer.delivery(envelope) async for v in stream: if v.block is None or v.block == '': msg = "fail to get block" _logger.error(msg) raise Exception(msg) block = v.block break block = BlockDecoder().decode(block.SerializeToString()) envelope = block['data']['data'][0] payload = envelope['payload'] channel_header = payload['header']['channel_header'] if channel_header['type'] != common_pb2.CONFIG: raise Exception(f'Block must be of type "CONFIG"' f' ({common_pb2.CONFIG}), but got' f' "{channel_header["type"]}" instead') config_envelope = payload['data'] return config_envelope