def get_events(self, tx_context, channel_name, start=None, stop=None, filtered=True, behavior='BLOCK_UNTIL_READY'): """ get the events of the channel. Return: the events in success or None in fail. """ _logger.info("get events") seek_info = create_seek_info(start, stop, behavior) kwargs = {} if self._client_cert_path: with open(self._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, channel_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 return self.delivery(envelope, filtered=filtered)
def get_genesis_block(self, tx_context, channel_name): """ get the genesis block of the channel. Return: the genesis block in success or None in fail. """ _logger.info("get genesis block - start") seek_info = create_seek_info(0, 0) seek_info_header = build_channel_header( common_pb2.HeaderType.Value('DELIVER_SEEK_INFO'), tx_context.tx_id, channel_name, current_timestamp(), tx_context.epoch) 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) response = self.delivery(envelope) if response[0].block is None or response[0].block == '': _logger.error("fail to get genesis block") return None _logger.info("get genesis block successfully, block=%s", response[0].block.header) return response[0].block
def join_channel(self, request): """ To join the peer to a channel. Args: request: the request to join a channel Return: True in sucess or False in failure """ _logger.debug('channel_join - start') for key in ['targets', 'block', 'tx_context']: if key not in request: err_msg = "Missing parameter {}".format(key) _logger.error('channel_join error: {}'.format(err_msg)) raise ValueError(err_msg) chaincode_input = chaincode_pb2.ChaincodeInput() chaincode_input.args.extend([proto_b("JoinChain"), request['block']]) chaincode_id = chaincode_pb2.ChaincodeID() chaincode_id.name = proto_str("cscc") cc_spec = create_cc_spec(chaincode_input, chaincode_id, 'GOLANG') cc_invoke_spec = chaincode_pb2.ChaincodeInvocationSpec() cc_invoke_spec.chaincode_spec.CopyFrom(cc_spec) tx_context = request['tx_context'] extension = proposal_pb2.ChaincodeHeaderExtension() extension.chaincode_id.name = proto_str('cscc') channel_header = build_channel_header( common_pb2.HeaderType.Value('ENDORSER_TRANSACTION'), tx_context.tx_id, '', current_timestamp(), tx_context.epoch, extension=extension.SerializeToString()) header = build_header(tx_context.identity, channel_header, tx_context.nonce) proposal = build_cc_proposal(cc_invoke_spec, header, request['transient_map']) try: responses = send_transaction_proposal(proposal, tx_context, request['targets']) except Exception as e: raise IOError("fail to send transanction proposal", e) q = Queue(1) result = True for r in responses: r.subscribe(on_next=lambda x: q.put(x), on_error=lambda x: q.put(x)) res = q.get(timeout=5) proposal_res = res[0] result = result and (proposal_res.response.status == 200) if result: _logger.info("successfully join the peers") return result
def test_build_header(self): timestamp = utils.current_timestamp() client = Client() client.state_store = FileKeyValueStore(self.kv_store_path) orderer_org_admin = get_orderer_org_admin(client) orderer_org_admin_tx_context = \ TXContext(orderer_org_admin, Ecies(), {}) client.tx_context = orderer_org_admin_tx_context orderer_org_admin_serialized = utils.create_serialized_identity( orderer_org_admin) serialized_identity = identities_pb2.SerializedIdentity() serialized_identity.ParseFromString(orderer_org_admin_serialized) proto_channel_header = utils.build_channel_header( common_pb2.HeaderType.Value('CONFIG_UPDATE'), orderer_org_admin_tx_context.tx_id, self.channel_id, timestamp ) channel_header = utils.build_header( orderer_org_admin_tx_context.identity, proto_channel_header, orderer_org_admin_tx_context.nonce ) self.assertIsInstance(channel_header, common_pb2.Header)
def get_genesis_block(self, tx_context, channel_name): """get the genesis block of the channel :return: the genesis block in success or None in fail :rtype: Block/None """ _logger.info("get genesis block - start") seek_info = create_seek_info(0, 0) kwargs = {} if self._client_cert_path: with open(self._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, channel_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 return self.delivery(envelope)
def get_block_between(self, tx_context, orderer, start, end): """ Args: tx_context: tx_context instance orderer: orderer instance start: id of block to start query for end: id of block to end query for Returns: block(s) """ seek_info = create_seek_info(start, end) seek_info_header = build_channel_header( common_pb2.HeaderType.Value('DELIVER_SEEK_INFO'), tx_context.tx_id, self._name, current_timestamp(), tx_context.epoch) 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) response = orderer.delivery(envelope) if response[0].block is None or response[0].block == '': _logger.error("fail to get block start from %s to %s" % (str(start), str(end))) return None _logger.info("get block successfully, start from %s to %s" % (str(start), str(end))) return response[0].block
def _get_stream(self): """ get the events of the channel. Return: the events in success or None in fail. """ _logger.info("create peer delivery stream") if self._signed_event is not None: return self._peer.delivery(self._signed_event, filtered=self._filtered) seek_info = self._create_seek_info(self._start, self._stop) kwargs = {} if self._peer._client_cert_path: with open(self._peer._client_cert_path, 'rb') as f: b64der = pem_to_der(f.read()) kwargs['tls_cert_hash'] = sha256(b64der).digest() tx_context = TXContext(self._requestor, self._requestor.cryptoSuite, TXProposalRequest()) seek_info_header = build_channel_header( common_pb2.HeaderType.Value('DELIVER_SEEK_INFO'), tx_context.tx_id, self._channel_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 return self._peer.delivery(envelope, filtered=self._filtered)
def _send_tx_proposal(channel_id, tx_context, peers, cc_type=CC_TYPE_GOLANG): request = tx_context.tx_prop_req args = [] if request.fcn: args.append(proto_b(request.fcn)) else: args.append(proto_b(CC_INVOKE)) for arg in request.args: if isinstance(arg, bytes): args.append(arg) else: args.append(proto_b(arg)) cc_id = chaincode_pb2.ChaincodeID() cc_id.name = request.cc_name if request.prop_type not in (CC_QUERY, CC_INVOKE): cc_id.version = request.cc_version cc_input = chaincode_pb2.ChaincodeInput() cc_input.args.extend(args) cc_spec = chaincode_pb2.ChaincodeSpec() cc_spec.type = chaincode_pb2.ChaincodeSpec.Type.Value(cc_type) cc_spec.chaincode_id.CopyFrom(cc_id) cc_spec.input.CopyFrom(cc_input) extension = proposal_pb2.ChaincodeHeaderExtension() extension.chaincode_id.name = request.cc_name cc_invoke_spec = chaincode_pb2.ChaincodeInvocationSpec() cc_invoke_spec.chaincode_spec.CopyFrom(cc_spec) channel_header = build_channel_header( common_pb2.ENDORSER_TRANSACTION, tx_context.tx_id, channel_id, current_timestamp(), tx_context.epoch, extension=extension.SerializeToString()) header = build_header(tx_context.identity, channel_header, tx_context.nonce) # chaincode real proposal proposal = build_cc_proposal(cc_invoke_spec, header, request.transient_map) signed_proposal = utils.sign_proposal(tx_context, proposal) responses = [peer.send_proposal(signed_proposal) for peer in peers] # chaincode proposal without transient map # https://jira.hyperledger.org/browse/FAB-12536?focusedCommentId=52438&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-52438 # noqa proposal = build_cc_proposal(cc_invoke_spec, header, None) return responses, proposal, header
def test_build_channel_header(self): timestamp = utils.current_timestamp() proto_channel_header = utils.build_channel_header( common_pb2.HeaderType.Value('CONFIG_UPDATE'), '12341234', self.channel_id, timestamp) self.assertIsInstance(proto_channel_header, common_pb2.ChannelHeader) self.assertEqual(proto_channel_header.channel_id, self.channel_id)
def get_genesis_block(self, tx_context, channel_name): "채널의 제네시스 블록 생성, 스트림으로 응답" seek_info_header = build_channel_header( common_pb2.HeaderType.Value('DELIVER_SEEK_INFO'), tx_context.tx_id, channel_name, current_timestamp(), tx_context.epoch, **kwargs ) return self.delivery(envelope)
def _send_tx_proposal(channel_id, tx_context, peers): request = tx_context.tx_prop_req args = [] if request.fcn: args.append(proto_b(request.fcn)) else: args.append(proto_b(CC_INVOKE)) for arg in request.args: if isinstance(arg, bytes): args.append(arg) else: args.append(proto_b(arg)) cc_id = chaincode_pb2.ChaincodeID() cc_id.name = request.cc_name if request.prop_type != CC_QUERY: cc_id.version = request.cc_version cc_input = chaincode_pb2.ChaincodeInput() cc_input.args.extend(args) cc_spec = chaincode_pb2.ChaincodeSpec() cc_spec.type = chaincode_pb2.ChaincodeSpec.Type.Value(CC_TYPE_GOLANG) cc_spec.chaincode_id.CopyFrom(cc_id) cc_spec.input.CopyFrom(cc_input) extension = proposal_pb2.ChaincodeHeaderExtension() extension.chaincode_id.name = request.cc_name cc_invoke_spec = chaincode_pb2.ChaincodeInvocationSpec() cc_invoke_spec.chaincode_spec.CopyFrom(cc_spec) channel_header = build_channel_header( common_pb2.ENDORSER_TRANSACTION, tx_context.tx_id, channel_id, current_timestamp(), tx_context.epoch, extension=extension.SerializeToString()) header = build_header(tx_context.identity, channel_header, tx_context.nonce) proposal = build_cc_proposal(cc_invoke_spec, header, request.transient_map) signed_proposal = utils.sign_proposal(tx_context, proposal) send_executions = [ peer.send_proposal(signed_proposal) for peer in peers ] return rx.Observable.merge(send_executions).to_iterable() \ .map(lambda responses: (responses, proposal, header))
def join_channel(self, request): """ To join the peer to a channel. Args: request: the request to join a channel Return: A coroutine to handle thanks to asyncio with await asyncio.gather(*responses) """ _logger.debug('channel_join - start') for key in ['targets', 'block', 'tx_context']: if key not in request: err_msg = "Missing parameter {}".format(key) _logger.error('channel_join error: {}'.format(err_msg)) raise ValueError(err_msg) chaincode_input = chaincode_pb2.ChaincodeInput() chaincode_input.args.extend([proto_b("JoinChain"), request['block']]) chaincode_id = chaincode_pb2.ChaincodeID() chaincode_id.name = proto_str("cscc") cc_spec = create_cc_spec(chaincode_input, chaincode_id, 'GOLANG') cc_invoke_spec = chaincode_pb2.ChaincodeInvocationSpec() cc_invoke_spec.chaincode_spec.CopyFrom(cc_spec) tx_context = request['tx_context'] extension = proposal_pb2.ChaincodeHeaderExtension() extension.chaincode_id.name = proto_str('cscc') channel_header = build_channel_header( common_pb2.HeaderType.Value('ENDORSER_TRANSACTION'), tx_context.tx_id, '', current_timestamp(), tx_context.epoch, extension=extension.SerializeToString()) header = build_header(tx_context.identity, channel_header, tx_context.nonce) proposal = build_cc_proposal(cc_invoke_spec, header, request['transient_map']) return send_transaction_proposal(proposal, tx_context, request['targets'])
def get_genesis_block(self, tx_context, channel_name): """ get the genesis block of the channel. Return: the genesis block in success or None in fail. """ _logger.info("get genesis block - start") seek_info = create_seek_info(0, 0) seek_info_header = build_channel_header( common_pb2.HeaderType.Value('DELIVER_SEEK_INFO'), tx_context.tx_id, channel_name, current_timestamp(), tx_context.epoch) 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 return self.delivery(envelope)
def get_genesis_block(self): """ get the genesis block of the channel. Return: the genesis block in success or None in fail. """ _logger.info("get genesis block - start") orderer = self._get_random_orderer() tx_context = self._client.tx_context seek_info = create_seek_info(0, 0) seek_info_header = build_channel_header( common_pb2.HeaderType.Value('DELIVER_SEEK_INFO'), tx_context.tx_id, self.name, current_timestamp(), tx_context.epoch) 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) q = Queue(1) response = orderer.delivery(envelope) response.subscribe(on_next=lambda x: q.put(x), on_error=lambda x: q.put(x)) res, _ = q.get(timeout=5) if res.block is None or res.block == '': _logger.error("fail to get genesis block") return None _logger.info("get genesis block successfully, block=%s", res.block.header) return res.block
def send_install_proposal(self, tx_context, peers=None, scheduler=None): """ Send install chaincode proposal Args: schedule: Rx schedule install_proposal_req: install proposal request targets: a set of peer to send Returns: a set of proposal response """ if peers is None: targets = self._peers.values() else: targets = peers # self._validate_state() # TODO: enable this later # self._validate_peers(targets) # TODO: enable this later if not tx_context: raise ValueError("InstallProposalRequest is null.") cc_deployment_spec = chaincode_pb2.ChaincodeDeploymentSpec() cc_deployment_spec.chaincode_spec.type = \ chaincode_pb2.ChaincodeSpec.Type.Value( proto_str(tx_context.tx_prop_req.cc_type)) cc_deployment_spec.chaincode_spec.chaincode_id.name = \ proto_str(tx_context.tx_prop_req.cc_name) cc_deployment_spec.chaincode_spec.chaincode_id.path = \ proto_str(tx_context.tx_prop_req.cc_path) cc_deployment_spec.chaincode_spec.chaincode_id.version = \ proto_str(tx_context.tx_prop_req.cc_version) if not self._is_dev_mode: if not tx_context.tx_prop_req.packaged_cc: cc_deployment_spec.code_package = \ self._package_chaincode( tx_context.tx_prop_req.cc_path, tx_context.tx_prop_req.cc_type) else: cc_deployment_spec.code_package = \ tx_context.tx_prop_req.packaged_cc cc_deployment_spec.effective_date.seconds = \ tx_context.tx_prop_req.effective_date.seconds cc_deployment_spec.effective_date.nanos = \ tx_context.tx_prop_req.effective_date.nanos channel_header_extension = proposal_pb2.ChaincodeHeaderExtension() channel_header_extension.chaincode_id.name = \ proto_str("lscc") channel_header = utils.build_channel_header( common_pb2.ENDORSER_TRANSACTION, tx_context.tx_id, '', utils.current_timestamp(), tx_context.epoch, channel_header_extension.SerializeToString()) header = utils.build_header(tx_context.identity, channel_header, tx_context.nonce) cci_spec = chaincode_pb2.ChaincodeInvocationSpec() cci_spec.chaincode_spec.type = \ chaincode_pb2.ChaincodeSpec.Type.Value(CC_TYPE_GOLANG) cci_spec.chaincode_spec.chaincode_id.name = proto_str("lscc") cci_spec.chaincode_spec.input.args.extend( [proto_b(CC_INSTALL), cc_deployment_spec.SerializeToString()]) proposal = utils.build_cc_proposal( cci_spec, header, tx_context.tx_prop_req.transient_map) signed_proposal = utils.sign_proposal(tx_context, proposal) send_executions = [ peer.send_proposal(signed_proposal, scheduler) for peer in targets ] return rx.Observable.merge(send_executions).to_iterable() \ .map(lambda responses: (responses, proposal, header))
def _send_cc_proposal(self, tx_context, command, peers): args = [] request = tx_context.tx_prop_req args.append(proto_b(request.fcn)) for arg in request.args: args.append(proto_b(arg)) # construct the deployment spec cc_id = chaincode_pb2.ChaincodeID() cc_id.name = request.cc_name cc_id.version = request.cc_version cc_input = chaincode_pb2.ChaincodeInput() cc_input.args.extend(args) cc_spec = create_cc_spec(cc_input, cc_id, CC_TYPE_GOLANG) cc_dep_spec = chaincode_pb2.ChaincodeDeploymentSpec() cc_dep_spec.chaincode_spec.CopyFrom(cc_spec) cc_dep_spec.effective_date.seconds = \ tx_context.tx_prop_req.effective_date.seconds cc_dep_spec.effective_date.nanos = \ tx_context.tx_prop_req.effective_date.nanos # construct the invoke spec # TODO: if the policy not provided, new one should be built. if request.cc_endorsement_policy: policy = request.cc_endorsement_policy else: policy = '' invoke_input = chaincode_pb2.ChaincodeInput() invoke_input.args.extend([ proto_b(command), proto_b(self.name), cc_dep_spec.SerializeToString(), proto_b(policy), proto_b('escc'), proto_b('vscc') ]) invoke_cc_id = chaincode_pb2.ChaincodeID() invoke_cc_id.name = proto_str('lscc') cc_invoke_spec = chaincode_pb2.ChaincodeInvocationSpec() cc_invoke_spec.chaincode_spec.CopyFrom( create_cc_spec(invoke_input, invoke_cc_id, CC_TYPE_GOLANG)) extension = proposal_pb2.ChaincodeHeaderExtension() extension.chaincode_id.name = proto_str('lscc') channel_header = build_channel_header( common_pb2.ENDORSER_TRANSACTION, tx_context.tx_id, self.name, current_timestamp(), epoch=0, extension=extension.SerializeToString()) header = build_header(tx_context.identity, channel_header, tx_context.nonce) proposal = build_cc_proposal(cc_invoke_spec, header, request.transient_map) signed_proposal = utils.sign_proposal(tx_context, proposal) send_executions = [ peer.send_proposal(signed_proposal) for peer in peers ] return rx.Observable.merge(send_executions).to_iterable() \ .map(lambda responses: (responses, proposal, header))
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
def _send_cc_proposal(self, tx_context, command, peers): args = [] request = tx_context.tx_prop_req args.append(proto_b(request.fcn)) for arg in request.args: args.append(proto_b(arg)) # construct the deployment spec cc_id = chaincode_pb2.ChaincodeID() cc_id.name = request.cc_name cc_id.version = request.cc_version cc_input = chaincode_pb2.ChaincodeInput() cc_input.args.extend(args) cc_spec = create_cc_spec(cc_input, cc_id, CC_TYPE_GOLANG) cc_dep_spec = chaincode_pb2.ChaincodeDeploymentSpec() cc_dep_spec.chaincode_spec.CopyFrom(cc_spec) cc_dep_spec.effective_date.seconds = \ tx_context.tx_prop_req.effective_date.seconds cc_dep_spec.effective_date.nanos = \ tx_context.tx_prop_req.effective_date.nanos # construct the invoke spec # TODO: if the policy not provided, new one should be built. if request.cc_endorsement_policy: policy = request.cc_endorsement_policy else: policy = '' invoke_input = chaincode_pb2.ChaincodeInput() invoke_input.args.extend([ proto_b(command), proto_b(self.name), cc_dep_spec.SerializeToString(), proto_b(policy), proto_b('escc'), proto_b('vscc') ]) invoke_cc_id = chaincode_pb2.ChaincodeID() invoke_cc_id.name = proto_str('lscc') cc_invoke_spec = chaincode_pb2.ChaincodeInvocationSpec() cc_invoke_spec.chaincode_spec.CopyFrom( create_cc_spec(invoke_input, invoke_cc_id, CC_TYPE_GOLANG)) extension = proposal_pb2.ChaincodeHeaderExtension() extension.chaincode_id.name = proto_str('lscc') channel_header = build_channel_header( common_pb2.ENDORSER_TRANSACTION, tx_context.tx_id, self.name, current_timestamp(), epoch=0, extension=extension.SerializeToString()) header = build_header(tx_context.identity, channel_header, tx_context.nonce) proposal = build_cc_proposal(cc_invoke_spec, header, request.transient_map) try: responses = send_transaction_proposal(proposal, header, tx_context, peers) except Exception as e: raise IOError("fail to send transanction proposal", e) q = Queue(1) result = True for r in responses: r.subscribe(on_next=lambda x: q.put(x), on_error=lambda x: q.put(x)) res, _ = q.get() result = result and (res.response.status == 200) return result
def _send_cc_proposal(self, tx_context, command, peers): args = [] request = tx_context.tx_prop_req args.append(proto_b(request.fcn)) for arg in request.args: args.append(proto_b(arg)) # construct the deployment spec cc_id = chaincode_pb2.ChaincodeID() cc_id.name = request.cc_name cc_id.version = request.cc_version cc_input = chaincode_pb2.ChaincodeInput() cc_input.args.extend(args) cc_spec = create_cc_spec(cc_input, cc_id, CC_TYPE_GOLANG) cc_dep_spec = chaincode_pb2.ChaincodeDeploymentSpec() cc_dep_spec.chaincode_spec.CopyFrom(cc_spec) # Pass msps, TODO create an MSPManager as done in fabric-sdk-node policy = self._build_policy(request.cc_endorsement_policy) args = [ proto_b(command), proto_b(self.name), cc_dep_spec.SerializeToString(), policy, proto_b('escc'), proto_b('vscc'), ] # collections_configs need V1_2 or later capability enabled, # otherwise private channel collections and data are not available collections_configs = [] if request.collections_config: for config in request.collections_config: static_config = collection_pb2.StaticCollectionConfig() static_config.name = config['name'] static_config.member_orgs_policy.signature_policy. \ CopyFrom(self._build_policy(config['policy'], returnProto=True)) static_config.maximum_peer_count = config['maxPeerCount'] static_config. \ required_peer_count = config.get('requiredPeerCount', 0) static_config.block_to_live = config.get('blockToLive', 0) static_config.member_only_read = config.get( 'memberOnlyRead', False) collections_config = collection_pb2.CollectionConfig() collections_config.static_collection_config.CopyFrom( static_config) collections_configs.append(collections_config) cc_coll_cfg = collection_pb2.CollectionConfigPackage() cc_coll_cfg.config.extend(collections_configs) args.append(cc_coll_cfg.SerializeToString()) # construct the invoke spec invoke_input = chaincode_pb2.ChaincodeInput() invoke_input.args.extend(args) invoke_cc_id = chaincode_pb2.ChaincodeID() invoke_cc_id.name = proto_str('lscc') cc_invoke_spec = chaincode_pb2.ChaincodeInvocationSpec() cc_invoke_spec.chaincode_spec.CopyFrom( create_cc_spec(invoke_input, invoke_cc_id, CC_TYPE_GOLANG)) extension = proposal_pb2.ChaincodeHeaderExtension() extension.chaincode_id.name = proto_str('lscc') channel_header = build_channel_header( common_pb2.ENDORSER_TRANSACTION, tx_context.tx_id, self.name, current_timestamp(), epoch=0, extension=extension.SerializeToString()) header = build_header(tx_context.identity, channel_header, tx_context.nonce) proposal = build_cc_proposal(cc_invoke_spec, header, request.transient_map) signed_proposal = utils.sign_proposal(tx_context, proposal) response = [peer.send_proposal(signed_proposal) for peer in peers] return response, proposal, header
def _send_cc_proposal(self, tx_context, command, peers): args = [] request = tx_context.tx_prop_req args.append(proto_b(request.fcn)) for arg in request.args: args.append(proto_b(arg)) # construct the deployment spec cc_id = chaincode_pb2.ChaincodeID() cc_id.name = request.cc_name cc_id.version = request.cc_version cc_input = chaincode_pb2.ChaincodeInput() cc_input.args.extend(args) cc_spec = create_cc_spec(cc_input, cc_id, CC_TYPE_GOLANG) cc_dep_spec = chaincode_pb2.ChaincodeDeploymentSpec() cc_dep_spec.chaincode_spec.CopyFrom(cc_spec) # Pass msps, TODO create an MSPManager as done in fabric-sdk-node policy = self._build_policy(request.cc_endorsement_policy) # construct the invoke spec invoke_input = chaincode_pb2.ChaincodeInput() invoke_input.args.extend( [proto_b(command), proto_b(self.name), cc_dep_spec.SerializeToString(), policy, proto_b('escc'), proto_b('vscc')]) invoke_cc_id = chaincode_pb2.ChaincodeID() invoke_cc_id.name = proto_str('lscc') cc_invoke_spec = chaincode_pb2.ChaincodeInvocationSpec() cc_invoke_spec.chaincode_spec.CopyFrom(create_cc_spec(invoke_input, invoke_cc_id, CC_TYPE_GOLANG) ) extension = proposal_pb2.ChaincodeHeaderExtension() extension.chaincode_id.name = proto_str('lscc') channel_header = build_channel_header( common_pb2.ENDORSER_TRANSACTION, tx_context.tx_id, self.name, current_timestamp(), epoch=0, extension=extension.SerializeToString() ) header = build_header(tx_context.identity, channel_header, tx_context.nonce) proposal = build_cc_proposal( cc_invoke_spec, header, request.transient_map) signed_proposal = utils.sign_proposal(tx_context, proposal) response = [peer.send_proposal(signed_proposal) for peer in peers] return response, proposal, header
def send_install_proposal(self, tx_context, peers=None): """Send install chaincode proposal :param install_proposal_req: install proposal request :param targets: a set of peer to send :param tx_context: a tx_context instance :param peers: peers (Default value = None) :return: a set of proposal response """ if peers is None: targets = self._peers.values() else: targets = peers # self._validate_state() # TODO: enable this later # self._validate_peers(targets) # TODO: enable this later if not tx_context: raise ValueError("InstallProposalRequest is null.") cc_deployment_spec = chaincode_pb2.ChaincodeDeploymentSpec() cc_deployment_spec.chaincode_spec.type = \ chaincode_pb2.ChaincodeSpec.Type.Value( utils.proto_str(tx_context.tx_prop_req.cc_type)) cc_deployment_spec.chaincode_spec.chaincode_id.name = \ proto_str(tx_context.tx_prop_req.cc_name) cc_deployment_spec.chaincode_spec.chaincode_id.path = \ proto_str(tx_context.tx_prop_req.cc_path) cc_deployment_spec.chaincode_spec.chaincode_id.version = \ proto_str(tx_context.tx_prop_req.cc_version) if not self._is_dev_mode: if not tx_context.tx_prop_req.packaged_cc: cc_deployment_spec.code_package = \ package_chaincode( tx_context.tx_prop_req.cc_path, tx_context.tx_prop_req.cc_type) else: cc_deployment_spec.code_package = \ tx_context.tx_prop_req.packaged_cc channel_header_extension = proposal_pb2.ChaincodeHeaderExtension() channel_header_extension.chaincode_id.name = \ proto_str("lscc") channel_header = utils.build_channel_header( common_pb2.ENDORSER_TRANSACTION, tx_context.tx_id, '', utils.current_timestamp(), tx_context.epoch, channel_header_extension.SerializeToString() ) header = utils.build_header(tx_context.identity, channel_header, tx_context.nonce) cci_spec = chaincode_pb2.ChaincodeInvocationSpec() cci_spec.chaincode_spec.type = \ chaincode_pb2.ChaincodeSpec.Type.Value(CC_TYPE_GOLANG) cci_spec.chaincode_spec.chaincode_id.name = proto_str("lscc") cci_spec.chaincode_spec.input.args.extend( [proto_b(CC_INSTALL), cc_deployment_spec.SerializeToString()]) proposal = utils.build_cc_proposal( cci_spec, header, tx_context.tx_prop_req.transient_map) signed_proposal = utils.sign_proposal(tx_context, proposal) responses = [peer.send_proposal(signed_proposal) for peer in targets] return responses, proposal, header
def _create_or_update_channel_request(self, request, have_envelope): """Inits the create of update channel process. Args: request (dct): A create_update channel request. have_envelope (bool): Signals if the requests contains a finished protobuf envelope. Returns: rx.Observable: An observable for the orderer_response or an error. """ _logger.debug('_create_or_update_channel - start') error_msg = None if 'config' not in request and not have_envelope: error_msg = 'Missing config request parameter containing ' \ 'the configuration of the channel' if 'signatures' not in request and not have_envelope: error_msg = 'Missing signatures request parameter for the ' \ 'new channel' elif 'signatures' in request and \ not isinstance(request['signatures'], list) \ and not have_envelope: error_msg = 'Signatures request parameter must be an array ' \ 'of signatures' if 'tx_id' not in request and not have_envelope: error_msg = 'Missing tx_id request parameter' if 'nonce' not in request and not have_envelope: error_msg = 'Missing nonce request parameter' if 'orderer' not in request: error_msg = 'Missing orderer request parameter' if 'channel_name' not in request: error_msg = 'Missing channel_name request parameter' if error_msg: _logger.error( '_create_or_update_channel error: {}'.format(error_msg)) raise ValueError(error_msg) if have_envelope: _logger.debug('_create_or_update_channel - have envelope') envelope = common_pb2.Envelope() envelope.ParseFromString(request['envelope']) signature = envelope.signature payload = envelope.payload else: _logger.debug('_create_or_update_channel - have config_update') proto_config_update_envelope = configtx_pb2.ConfigUpdateEnvelope() proto_config_update_envelope.config_update = request['config'] # convert signatures to protobuf signature signatures = request['signatures'] proto_signatures = utils.string_to_signature(signatures) proto_config_update_envelope.signatures.extend(proto_signatures) proto_channel_header = utils.build_channel_header( common_pb2.HeaderType.Value('CONFIG_UPDATE'), request['tx_id'], request['channel_name'], utils.current_timestamp()) proto_header = utils.build_header(self.tx_context.identity, proto_channel_header, request['nonce']) proto_payload = common_pb2.Payload() proto_payload.header.CopyFrom(proto_header) proto_payload.data = proto_config_update_envelope \ .SerializeToString() payload_bytes = proto_payload.SerializeToString() signature_bytes = self.tx_context.sign(payload_bytes) signature = signature_bytes payload = payload_bytes # assemble the final envelope out_envelope = common_pb2.Envelope() out_envelope.signature = signature out_envelope.payload = payload orderer = request['orderer'] return orderer.broadcast(out_envelope)
def join_channel(self, request): """ To join the peer to a channel. Args: request: the request to join a channel Return: True in sucess or False in failure """ _logger.debug('join_channel - start') err_msg = None if (not request): err_msg = "Missing all required input request parameters" if 'targets' not in request: err_msg = "Missing peers parameter" if 'block' not in request: err_msg = "Missing genesis block parameter" if 'tx_id' not in request: err_msg = "Missing transaction id parameter" if err_msg: _logger.error('join_channel error: {}'.format(err_msg)) raise ValueError(err_msg) tx_context = self._client.tx_context chaincode_spec = create_chaincode_spec(request['block'], 'cscc', "GOLANG") extension = chaincode_spec.SerializeToString() channel_header = build_channel_header( common_pb2.HeaderType.Value('ENDORSER_TRANSACTION'), tx_context.tx_id, self.name, current_timestamp(), tx_context.epoch, extension=extension) creator = create_serialized_identity(tx_context.user) header = build_header(creator, channel_header, tx_context.nonce) proposal = build_cc_proposal(chaincode_spec, header, {}) try: responses = send_transaction_proposal(proposal, header, tx_context, request['targets']) except Exception as e: raise IOError("fail to send transanction proposal", e) q = Queue(1) for r in responses: r.subscribe(on_next=lambda x: q.put(x), on_error=lambda x: q.put(x)) res = q.get(timeout=5) result = True and (res.response.status == 200) _logger.info("The return status is:", result) return result