def _build_channel_header(type, tx_id, channel_id, timestamp, epoch=0, extension=None): """Build channel. Args: extension: extension timestamp: timestamp channel_id: channel id tx_id: transaction id type: type epoch: epoch Returns: common_proto.Header instance """ channel_header = common_pb2.ChannelHeader() channel_header.type = type channel_header.version = 1 channel_header.channel_id = proto_str(channel_id) channel_header.tx_id = proto_str(tx_id) channel_header.epoch = epoch channel_header.timestamp = timestamp if extension: channel_header.extension = extension return channel_header
def _build_header(creator, nonce, type, chain_id, tx_id, epoch, cc_name): """Build a header for transaction proposal. Args: creator: user nonce: nonce type: transaction type chain_id: chain id tx_id: tx id epoch: epoch cc_name: chaincode name Returns: common_proto.Header instance """ header = common_proto.Header() header.signature_header.creator = creator.serialize() header.signature_header.nonce = nonce header.channel_header.type = type header.channel_header.version = 1 header.channel_header.channel_id = proto_str(chain_id) header.channel_header.tx_id = proto_str(tx_id) if epoch: header.channel_header.epoch = epoch if cc_name: header_ext = proposal_pb2.ChaincodeHeaderExtension() header_ext.chaincode_id.name = proto_str(cc_name) header.channel_header.extension = header_ext.SerializeToString() return header
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 _build_channel_header(type, tx_id, channel_id, timestamp, epoch=0, extension=None): """Build channel. :param extension: extension (Default value = None) :param timestamp: timestamp :param channel_id: channel id :param tx_id: transaction id :param type: type :param epoch: epoch :return: common_proto.Header instance (Default value = 0) """ channel_header = common_pb2.ChannelHeader() channel_header.type = type channel_header.version = 1 channel_header.channel_id = proto_str(channel_id) channel_header.tx_id = proto_str(tx_id) channel_header.epoch = epoch channel_header.timestamp = timestamp if extension: channel_header.extension = extension return channel_header
def _create_installment_proposal(tran_prop_req, signing_identity, chain): """Create a chaincode install proposal This involves assembling the proposal with the data (chaincodeID, chaincode invocation spec, etc.) and signing it using the private key corresponding to the ECert to sign. Args: chain: chain signing_identity: signing_identity tran_prop_req: see TransactionProposalRequest Returns: (Proposal): The created Proposal instance or None. """ cc_deployment_spec = chaincode_pb2.ChaincodeDeploymentSpec() cc_deployment_spec.chaincode_spec.type = \ chaincode_pb2.ChaincodeSpec.Type.Value('GOLANG') cc_deployment_spec.chaincode_spec.chaincode_id.name = \ proto_str(tran_prop_req.chaincode_id) cc_deployment_spec.chaincode_spec.chaincode_id.path = \ proto_str(tran_prop_req.chaincode_path) cc_deployment_spec.chaincode_spec.chaincode_id.version = \ proto_str(tran_prop_req.chaincode_version) if not chain.is_dev_mode: cc_deployment_spec.code_package = _package_chaincode( tran_prop_req.chaincode_path) if not \ tran_prop_req.chaincode_package else \ tran_prop_req.chaincode_package cc_deployment_spec.effective_date.seconds = \ tran_prop_req.effective_date.seconds cc_deployment_spec.effective_date.nanos = \ tran_prop_req.effective_date.nanos header = build_header(signing_identity, tran_prop_req.nonce, common_pb2.ENDORSER_TRANSACTION, chain, tran_prop_req.prop_type, chaincode_id="lscc") cci_spec = chaincode_pb2.ChaincodeInvocationSpec() cci_spec.chaincode_spec.type = \ chaincode_pb2.ChaincodeSpec.Type.Value('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 = build_proposal(cci_spec, header) return proposal, header
def _create_deployment_proposal(cc_deployment_req): """Create a chaincode deploy proposal This involves assembling the proposal with the data (chaincodeID, chaincode invocation spec, etc.) and signing it using the private key corresponding to the ECert to sign. Args: cc_deployment_req: see ChaincodeDeploymentRequest Returns: (Proposal): The created Proposal instance or None. """ _logger.debug('Create deployment proposal with ' 'chaincode_name={},chaincode_path={}'.format( cc_deployment_req.chaincode_name, cc_deployment_req.chaincode_path)) args_str = [cc_deployment_req.fcn] + cc_deployment_req.args cc_deployment_spec = chaincode_proto.ChaincodeDeploymentSpec() cc_deployment_spec.chaincode_spec.type = \ chaincode_proto.ChaincodeSpec.Type.Value('GOLANG') cc_deployment_spec.chaincode_spec.chaincode_id.name = \ proto_str(cc_deployment_req.chaincode_name) cc_deployment_spec.chaincode_spec.chaincode_id.path = \ proto_str(cc_deployment_req.chaincode_path) cc_deployment_spec.chaincode_spec.input.args.extend( list(map(lambda x: proto_b(x), args_str))) cc_deployment_spec.code_package = _package_chaincode( cc_deployment_req.chaincode_path) header = _build_header(cc_deployment_req.signing_identity, cc_deployment_req.nonce, common_proto.ENDORSER_TRANSACTION, cc_deployment_req.chain_id, cc_deployment_req.tx_id, None, cc_deployment_req.chaincode_name) cci_spec = chaincode_proto.ChaincodeInvocationSpec() cci_spec.chaincode_spec.type = \ chaincode_proto.ChaincodeSpec.Type.Value('GOLANG') cci_spec.chaincode_spec.chaincode_id.name = proto_str("lccc") cci_spec.chaincode_spec.input.args.extend( [b'deploy', b'default', cc_deployment_spec.SerializeToString()]) proposal = _build_proposal(cci_spec, header) # TODO: get signing_identity # signed_proposal = _sign_proposal( # cc_deployment_req.signing_identity, proposal) return proposal
def _create_instantiation_proposal(tran_prop_req, chain): """Create a chaincode instantiation proposal This involves assembling the proposal with the data (chaincodeID, chaincode invocation spec, etc.) and signing it using the private key corresponding to the ECert to sign. Args: tran_prop_req: see TransactionProposalRequest Returns: (Proposal): The created Proposal instance or None. """ args = ["init" if not tran_prop_req.fcn else tran_prop_req.fcn] + tran_prop_req.args cc_deployment_spec = chaincode_pb2.ChaincodeDeploymentSpec() cc_deployment_spec.chaincode_spec.type = \ chaincode_pb2.ChaincodeSpec.Type.Value('GOLANG') cc_deployment_spec.chaincode_spec.chaincode_id.name = \ proto_str(tran_prop_req.chaincode_id) cc_deployment_spec.chaincode_spec.chaincode_id.path = \ proto_str(tran_prop_req.chaincode_path) cc_deployment_spec.chaincode_spec.chaincode_id.version = \ proto_str(tran_prop_req.chaincode_version) cc_deployment_spec.chaincode_spec.input.args.extend(list(map( lambda x: proto_b(x), args))) header = build_header(tran_prop_req.signing_identity, tran_prop_req.nonce, common_pb2.ENDORSER_TRANSACTION, chain, tran_prop_req.prop_type, chaincode_id=tran_prop_req.chaincode_id ) cci_spec = chaincode_pb2.ChaincodeInvocationSpec() cci_spec.chaincode_spec.type = \ chaincode_pb2.ChaincodeSpec.Type.Value('GOLANG') cci_spec.chaincode_spec.chaincode_id.name = proto_str("lccc") cci_spec.chaincode_spec.input.args.extend( [proto_b(CC_INSTANTIATE), proto_b('default'), cc_deployment_spec.SerializeToString()]) proposal = build_proposal(cci_spec, header) signed_proposal = sign_proposal( tran_prop_req.signing_identity, proposal) return signed_proposal
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 build_header(creator, nonce, tran_prop_type, chain, prop_type, epoch=0, chaincode_id=None): """Build a header for transaction proposal. Args: prop_type: prop type creator: user nonce: nonce tran_prop_type: transaction proposal type chain: chain instance epoch: epoch chaincode_id: chaincode id Returns: common_proto.Header instance """ header = common_pb2.Header() signature_header = common_pb2.SignatureHeader() signature_header.creator = creator.serialize() signature_header.nonce = nonce header.signature_header = signature_header.SerializeToString() channel_header = common_pb2.ChannelHeader() channel_header.type = tran_prop_type channel_header.version = 1 if prop_type != CC_INSTALL: channel_header.channel_id = proto_str(chain.name) channel_header.tx_id = proto_str(chain.generate_tx_id(nonce, creator)) channel_header.epoch = epoch if chaincode_id: header_ext = proposal_pb2.ChaincodeHeaderExtension() header_ext.chaincode_id.name = proto_str(chaincode_id) channel_header.extension = header_ext.SerializeToString() header.channel_header = channel_header.SerializeToString() return header
def _create_invocation_proposal(tran_prop_req, chain): """Create a chaincode invocation proposal This involves assembling the proposal with the data (chaincodeID, chaincode invocation spec, etc.) and signing it using the private key corresponding to the ECert to sign. Args: tran_prop_req: see TransactionProposalRequest Returns: (Proposal): The created Proposal instance or None. """ args = ["invoke" if not tran_prop_req.fcn else tran_prop_req.fcn] + tran_prop_req.args if tran_prop_req.bytes_args: args += tran_prop_req.bytes_args header = build_header(tran_prop_req.signing_identity, tran_prop_req.nonce, common_pb2.ENDORSER_TRANSACTION, chain, tran_prop_req.prop_type, chaincode_id=tran_prop_req.chaincode_id ) cci_spec = chaincode_pb2.ChaincodeInvocationSpec() cci_spec.chaincode_spec.type = \ chaincode_pb2.ChaincodeSpec.Type.Value('GOLANG') cci_spec.chaincode_spec.chaincode_id.name = \ proto_str(tran_prop_req.chaincode_id) cci_spec.chaincode_spec.chaincode_id.version = \ proto_str(tran_prop_req.chaincode_version) cci_spec.chaincode_spec.input.args.extend(list(map( lambda x: proto_b(x), args))) proposal = build_proposal(cci_spec, header) signed_proposal = sign_proposal( tran_prop_req.signing_identity, proposal) return signed_proposal
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))
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) # 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_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 _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_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