From 665fc6162e5cef7979df06a31c836c6ef3b4d0d9 Mon Sep 17 00:00:00 2001 From: Jim Zhang Date: Sun, 5 Mar 2017 02:12:15 -0500 Subject: [PATCH] Create default policy of 'Signed By any member of org' FAB-2617 initial step to support chaincode policy during instantiate. The instantiate call always creates a "signed by any member of org by mspid" where the mspid is the submitting user's local msp. this guarantees that the default policy will always work. enhanced policy support will be added in a later changeset. Change-Id: Iede86d1c2d296141deec79ee6f7cd12502cc1238 Signed-off-by: Jim Zhang --- fabric-client/lib/Chain.js | 120 +++++++++------------ test/integration/e2e.js | 3 +- test/integration/e2e/invoke-transaction.js | 5 +- 3 files changed, 53 insertions(+), 75 deletions(-) diff --git a/fabric-client/lib/Chain.js b/fabric-client/lib/Chain.js index 39670a1f5a..fb4650f101 100644 --- a/fabric-client/lib/Chain.js +++ b/fabric-client/lib/Chain.js @@ -1641,20 +1641,25 @@ var Chain = class { let chaincodeDeploymentSpec = new _ccProto.ChaincodeDeploymentSpec(); chaincodeDeploymentSpec.setChaincodeSpec(ccSpec); - let lcccSpec = { - type: _ccProto.ChaincodeSpec.Type.GOLANG, - chaincode_id: { - name: 'lccc' - }, - input: { - args: [Buffer.from('deploy', 'utf8'), Buffer.from('default', 'utf8'), chaincodeDeploymentSpec.toBuffer()] - } - }; - var header, proposal; return self._clientContext.getUserContext() .then( function(userContext) { + let lcccSpec = { + type: _ccProto.ChaincodeSpec.Type.GOLANG, + chaincode_id: { + name: 'lccc' + }, + input: { + args: [ + Buffer.from('deploy', 'utf8'), + Buffer.from('default', 'utf8'), + chaincodeDeploymentSpec.toBuffer(), + self._buildChaincodePolicy(userContext.mspImpl._id) + ] + } + }; + var channelHeader = buildChannelHeader( _commonProto.HeaderType.ENDORSER_TRANSACTION, request.chainId, @@ -1949,7 +1954,40 @@ var Chain = class { return proposal; } - // internal utility method to return one Promise when sending a proposal to many peers + // internal utility method to build chaincode policy + // FIXME: for now always construct a 'Signed By any member of an organization by mspid' policy + _buildChaincodePolicy(mspid) { + // construct a list of msp principals to select from using the 'n out of' operator + var onePrn = new _mspPrProto.MSPPrincipal(); + onePrn.setPrincipalClassification(_mspPrProto.MSPPrincipal.Classification.ROLE); + + var memberRole = new _mspPrProto.MSPRole(); + memberRole.setRole(_mspPrProto.MSPRole.MSPRoleType.MEMBER); + memberRole.setMspIdentifier(mspid); + + onePrn.setPrincipal(memberRole.toBuffer()); + + // construct 'signed by msp principal at index 0' + var signedBy = new _policiesProto.SignaturePolicy(); + signedBy.set('signed_by', 0); + + // construct 'one of one' policy + var oneOfone = new _policiesProto.SignaturePolicy.NOutOf(); + oneOfone.setN(1); + oneOfone.setPolicies([signedBy]); + + var noutof = new _policiesProto.SignaturePolicy(); + noutof.set('n_out_of', oneOfone); + + var envelope = new _policiesProto.SignaturePolicyEnvelope(); + envelope.setVersion(0); + envelope.setPolicy(noutof); + envelope.setIdentities([onePrn]); + + return envelope.toBuffer(); + } + + // internal utility method to return one Promise when sending a proposal to many peers /** * @private */ @@ -2141,10 +2179,6 @@ var Chain = class { }; -function toKeyValueStoreName(name) { - return 'member.' + name; -} - //utility method to build a common chain header function buildChannelHeader(type, chain_id, tx_id, epoch, chaincode_id, time_stamp) { logger.debug('buildChannelHeader - type %s chain_id %s tx_id %d epoch % chaincode_id %s', @@ -2186,62 +2220,6 @@ function buildHeader(creator, channelHeader, nonce) { return header; } -//utility method to build a signed configuration item -function buildSignedConfigurationItem( - type, - last_modified, - mod_policy, - key, - value, - signatures) { - var configurationItem = new _configtxProto.ConfigurationItem(); - configurationItem.setType(type); // ConfigurationType - configurationItem.setLastModified(last_modified); // uint64 - configurationItem.setModificationPolicy(mod_policy); // ModificationPolicy - configurationItem.setKey(key); // string - configurationItem.setValue(value); // bytes - - var signedConfigurationItem = new _configtxProto.SignedConfigurationItem();//to do - this proto has changed drastically - signedConfigurationItem.setConfigurationItem(configurationItem.toBuffer()); - if(signatures) { - signedConfigurationItem.setSignatures(signatures); - } - - return signedConfigurationItem; -}; - -//utility method to build an accept all policy -function buildAcceptAllPolicy() { - return buildPolicyEnvelope(0); -} - -//utility method to build a reject all policy -function buildRejectAllPolicy() { - return buildPolicyEnvelope(1); -} - -//utility method to build a policy with a signature policy envelope -function buildPolicyEnvelope(nOf) { - logger.debug('buildPolicyEnvelope - building policy with nOf::'+nOf); - var nOutOf = new _policiesProto.SignaturePolicy.NOutOf(); - nOutOf.setN(nOf); - nOutOf.setPolicies([]); - var signaturePolicy = new _policiesProto.SignaturePolicy(); - signaturePolicy.setFrom(nOutOf); - var signaturePolicyEnvelope = new _policiesProto.SignaturePolicyEnvelope(); - signaturePolicyEnvelope.setVersion(0); - signaturePolicyEnvelope.setPolicy(signaturePolicy); -// var identity = new _mspPrProto.MSPPrincipal(); -// identity.setPrincipalClassification(_mspPrProto.MSPPrincipal.Classification.ByIdentity); -// identity.setPrincipal(Buffer.from('Admin')); - signaturePolicyEnvelope.setIdentities([]); - - var policy = new _policiesProto.Policy(); - policy.setType(_policiesProto.Policy.PolicyType.SIGNATURE); - policy.setPolicy(signaturePolicyEnvelope.toBuffer()); - return policy; -}; - //utility method to return a timestamp for the current time function buildCurrentTimestamp() { logger.debug('buildCurrentTimestamp - building'); diff --git a/test/integration/e2e.js b/test/integration/e2e.js index f14d13cdeb..94ed217bd4 100644 --- a/test/integration/e2e.js +++ b/test/integration/e2e.js @@ -1,4 +1,5 @@ require('./e2e/create-channel.js'); require('./e2e/join-channel.js'); require('./e2e/install-chaincode.js'); -require('./e2e/instantiate-chaincode.js'); \ No newline at end of file +require('./e2e/instantiate-chaincode.js'); +require('./e2e/invoke-transaction.js'); \ No newline at end of file diff --git a/test/integration/e2e/invoke-transaction.js b/test/integration/e2e/invoke-transaction.js index 4611819989..35937d464c 100644 --- a/test/integration/e2e/invoke-transaction.js +++ b/test/integration/e2e/invoke-transaction.js @@ -157,15 +157,14 @@ test('\n\n***** End-to-end flow: instantiate chaincode *****', (t) => { let handle = setTimeout(reject, 30000); eh.registerTxEvent(deployId.toString(), (tx, code) => { - t.pass('The chaincode deploy transaction has been committed on peer '+ eh.ep.addr); clearTimeout(handle); eh.unregisterTxEvent(deployId); if (code !== 'VALID') { - t.fail('The chaincode deploy transaction was invalid, code = ' + code); + t.fail('The balance transfer transaction was invalid, code = ' + code); reject(); } else { - t.pass('The chaincode deploy transaction was valid.'); + t.pass('The balance transfer transaction has been committed on peer '+ eh.ep.addr); resolve(); } });