diff --git a/build/tasks/watch.js b/build/tasks/watch.js
index ba58a15171..0e70d75f7d 100644
--- a/build/tasks/watch.js
+++ b/build/tasks/watch.js
@@ -10,7 +10,10 @@ gulp.task('watch', function () {
watch([
'hfc/lib/**/*',
- 'hfc-cop/lib/**/*'
+ 'hfc/index.js',
+ 'hfc/config/**/*',
+ 'hfc-cop/lib/**/*',
+ 'hfc-cop/config/**/*'
], { ignoreInitial: false, base: './' })
.pipe(debug())
.pipe(gulp.dest('node_modules'));
diff --git a/hfc-cop/config/default.json b/hfc-cop/config/default.json
index f9d144448a..750c64de22 100644
--- a/hfc-cop/config/default.json
+++ b/hfc-cop/config/default.json
@@ -2,7 +2,7 @@
"request-timeout" : 3000,
"tcert-batch-size" : 10,
"crypto-asymmetric-key-algo": "ECDSA",
- "crypto-hash-algo": "SHA3",
- "crypto-keysize": 384,
+ "crypto-hash-algo": "SHA2",
+ "crypto-keysize": 256,
"crypto-suite": "./impl/CryptoSuite_ECDSA_AES.js",
}
diff --git a/hfc/config/default.json b/hfc/config/default.json
index 5e70335fa6..9374f76da1 100644
--- a/hfc/config/default.json
+++ b/hfc/config/default.json
@@ -2,8 +2,8 @@
"request-timeout" : 3000,
"tcert-batch-size" : 10,
"crypto-asymmetric-key-algo": "ECDSA",
- "crypto-hash-algo": "SHA3",
- "crypto-keysize": 384,
+ "crypto-hash-algo": "SHA2",
+ "crypto-keysize": 256,
"crypto-suite": "./impl/CryptoSuite_ECDSA_AES.js",
"key-value-store": "./impl/FileKeyValueStore.js",
"member-service": "./impl/FabricCOPImpl.js",
diff --git a/hfc/index.js b/hfc/index.js
index e4cd43731a..f3de967bc0 100644
--- a/hfc/index.js
+++ b/hfc/index.js
@@ -198,3 +198,29 @@ module.exports.getConfigSetting = function(name, default_value) {
return utils.getConfigSetting(name, default_value);
};
+/**
+ * Builds an unique transaction ID based on the values in
+ * the request object.
+ *
+ * @param {Object} request - An object with the values to be used
+ * to build an unique transaction ID.
+ * @returns {String} An unique transaction ID
+ */
+module.exports.buildTransactionID = function(request) {
+
+ return utils.buildTransactionID(request);
+};
+
+/**
+ * Gets a random number for a one time use
+ *
+ * @param {int} length - Optional value to control the length of the number.
+ * The configuration setting 'nonce-size' will be used if not
+ * passed in.
+ * @return {int} Random number of the specified length
+ */
+module.exports.getNonce = function(length) {
+
+ return utils.buildTransactionID(length);
+};
+
diff --git a/hfc/lib/Chain.js b/hfc/lib/Chain.js
index 6c48a0893e..330e8a3549 100644
--- a/hfc/lib/Chain.js
+++ b/hfc/lib/Chain.js
@@ -208,7 +208,9 @@ var Chain = class {
member.restoreState()
.then(
function() {
- self._members[name] = member;
+ if (member.isEnrolled()) {
+ self._members[name] = member;
+ }
logger.debug('Requested member "%s" loaded from key value store', name);
return resolve(member);
}
diff --git a/hfc/lib/Member.js b/hfc/lib/Member.js
index a94a6d0609..65c41bffb7 100644
--- a/hfc/lib/Member.js
+++ b/hfc/lib/Member.js
@@ -29,7 +29,6 @@ var _ccProto = grpc.load(__dirname + '/protos/peer/chaincode.proto').protos;
var _ccProposalProto = grpc.load(__dirname + '/protos/peer/chaincode_proposal.proto').protos;
var _ccTransProto = grpc.load(__dirname + '/protos/peer/chaincode_transaction.proto').protos;
var _transProto = grpc.load(__dirname + '/protos/peer/fabric_transaction.proto').protos;
-var _headerProto = grpc.load(__dirname + '/protos/peer/fabric_transaction_header.proto').protos;
var _proposalProto = grpc.load(__dirname + '/protos/peer/fabric_proposal.proto').protos;
var _responseProto = grpc.load(__dirname + '/protos/peer/fabric_proposal_response.proto').protos;
var _commonProto = grpc.load(__dirname + '/protos/common/common.proto').common;
@@ -241,18 +240,34 @@ var Member = class {
* This will be an acknowledgement from the orderer of successfully submitted transaction.
* @see the ./proto/atomicbroadcast/ab.proto
*/
- sendTransaction(proposalResponses, chaincodeProposal) {
+ sendTransaction(request) {
logger.debug('Member.sendTransaction - start :: chain '+this._chain);
+ var errorMsg = null;
- // Verify that data is being passed in
- if (!proposalResponses) {
- logger.error('Member.sendTransaction - input proposalResponse missing');
- return Promise.reject(new Error('Missing proposalResponse object parameter'));
+ if (request) {
+ // Verify that data is being passed in
+ if (!request.proposalResponses) {
+ errorMsg = 'Missing "proposalResponse" parameter in transaction request';
+ }
+ if (!request.proposal) {
+ errorMsg = 'Missing "proposal" parameter in transaction request';
+ }
+ if (!request.header) {
+ errorMsg = 'Missing "header" parameter in transaction request';
+ }
+ } else {
+ errorMsg = 'Missing input request object on the proposal request';
}
- if (!chaincodeProposal) {
- logger.error('Member.sendTransaction - input chaincodeProposal missing');
- return Promise.reject(new Error('Missing chaincodeProposal object parameter'));
+
+ if(errorMsg) {
+ logger.error('Member.sendTransaction error '+ errorMsg);
+ return Promise.reject(new Error(errorMsg));
}
+
+ let proposalResponses = request.proposalResponses;
+ let chaincodeProposal = request.proposal;
+ let header = request.header;
+
// verify that we have an orderer configured
if(!this._chain.getOrderer()) {
logger.error('Member.sendTransaction - no orderer defined');
@@ -274,36 +289,43 @@ var Member = class {
endorsements.push(proposalResponse.endorsement);
}
-// logger.debug('Member.sendTransaction - proposalResponse %j', proposalResponse);
-// logger.debug('Member.sendTransaction - chaincodePropsoal %j', chaincodeProposal);
-
var chaincodeEndorsedAction = new _ccTransProto.ChaincodeEndorsedAction();
chaincodeEndorsedAction.setProposalResponsePayload(proposalResponse.payload);
chaincodeEndorsedAction.setEndorsements(endorsements);
var chaincodeActionPayload = new _ccTransProto.ChaincodeActionPayload();
chaincodeActionPayload.setAction(chaincodeEndorsedAction);
- chaincodeActionPayload.setChaincodeProposalPayload(chaincodeProposal.payload);
+ var chaincodeProposalPayloadNoTrans = _ccProposalProto.ChaincodeProposalPayload.decode(chaincodeProposal.payload);
+ chaincodeProposalPayloadNoTrans.transient = null;
+ var payload_hash = this._chain.cryptoPrimitives.hash(chaincodeProposalPayloadNoTrans.toBuffer());
+ chaincodeActionPayload.setChaincodeProposalPayload(Buffer.from(payload_hash, 'hex'));
+
+ //let header = Member._buildHeader(this._enrollment.certificate, request.chainId, request.chaincodeId, request.txId, request.nonce);
var transactionAction = new _transProto.TransactionAction();
- transactionAction.setHeader(chaincodeProposal.header);
+ transactionAction.setHeader(header.getSignatureHeader().toBuffer());
transactionAction.setPayload(chaincodeActionPayload.toBuffer());
var actions = [];
actions.push(transactionAction);
- var transaction2 = new _transProto.Transaction2();
- transaction2.setActions(actions);
+ var transaction = new _transProto.Transaction();
+ transaction.setActions(actions);
- let header = Member._buildHeader(this._enrollment.certificate, null);
var payload = new _commonProto.Payload();
payload.setHeader(header);
- payload.setData(transaction2.toBuffer());
+ payload.setData(transaction.toBuffer());
+
+ let payload_bytes = payload.toBuffer();
+ // sign the proposal
+ let sig = this._chain.cryptoPrimitives.sign(this._enrollment.privateKey, payload_bytes);
+ let signature = Buffer.from(sig.toDER());
// building manually or will get protobuf errors on send
var envelope = {
- payload : payload.toBuffer()
+ signature: signature,
+ payload : payload_bytes
};
var orderer = this._chain.getOrderer();
@@ -317,6 +339,9 @@ var Member = class {
*
`targets` : required - An array or single Endorsing {@link Peer} objects as the targets of the request
*
`chaincodePath` : required - String of the path to location of the source code of the chaincode
*
`chaincodeId` : required - String of the name of the chaincode
+ *
`chainId` : required - String of the name of the chain
+ *
`txId` : required - String of the transaction id
+ *
`nonce` : required - Integer of the once time number
*
`fcn` : optional - String of the function to be called on the chaincode once deployed (default 'init')
*
`args` : optional - String Array arguments specific to the chaincode being deployed
*
`dockerfile-contents` : optional - String defining the
@@ -324,21 +349,18 @@ var Member = class {
* @see /protos/peer/fabric_proposal_response.proto
*/
sendDeploymentProposal(request) {
- // Verify that chaincodePath is being passed
- if (!request.chaincodePath || request.chaincodePath === '') {
- logger.error('Invalid input parameter to "sendDeploymentProposal": must have "chaincodePath"');
- return Promise.reject(new Error('Missing chaincodePath in Deployment proposal request'));
- }
+ var errorMsg = null;
- if(!request.chaincodeId) {
- logger.error('Missing chaincodeId in the Deployment proposal request');
- return Promise.reject(new Error('Missing chaincodeId in the Deployment proposal request'));
+ // Verify that chaincodePath is being passed
+ if (request && (!request.chaincodePath || request.chaincodePath === '')) {
+ errorMsg = 'Missing chaincodePath parameter in Deployment proposal request';
+ } else {
+ errorMsg = Member._checkProposalRequest(request);
}
- // verify that the caller has included a peer object
- if(!request.targets) {
- logger.error('Invalid input parameter to "sendDeploymentProposal": must have "targets" object');
- return Promise.reject(new Error('Missing "targets" for the endorsing peer objects in the Deployment proposal request'));
+ if(errorMsg) {
+ logger.error('Member.sendDeploymentProposal error '+ errorMsg);
+ return Promise.reject(new Error(errorMsg));
}
// args is optional because some chaincode may not need any input parameters during initialization
@@ -395,13 +417,14 @@ var Member = class {
}
};
- let proposal = self._buildProposal(lcccSpec, 'lccc');
- let signed_proposal = self._signProposal(proposal);
+ let header = Member._buildHeader(self._enrollment.certificate, request.chainId, 'lccc', request.txId, request.nonce);
+ let proposal = self._buildProposal(lcccSpec, header);
+ let signed_proposal = self._signProposal(self._enrollment, proposal);
return Member._sendPeersProposal(request.targets, signed_proposal)
.then(
function(responses) {
- resolve([responses, proposal]);
+ resolve([responses, proposal, header]);
}
).catch(
function(err) {
@@ -427,27 +450,25 @@ var Member = class {
* @param {Object} request
*
`targets` : An array or single Endorsing {@link Peer} objects as the targets of the request
*
`chaincodeId` : The id of the chaincode to perform the transaction proposal
+ *
`chainId` : required - String of the name of the chain
+ *
`txId` : required - String of the transaction id
+ *
`nonce` : required - Integer of the once time number
*
`args` : an array of arguments specific to the chaincode 'innvoke'
* @returns {Promise} A Promise for a `ProposalResponse`
*/
sendTransactionProposal(request) {
logger.debug('Member.sendTransactionProposal - start');
-
- // verify that the caller has included a peer object
- if(!request.targets) {
- logger.error('Missing "targets" endorser peer objects in the Transaction proposal request');
- return Promise.reject(new Error('Missing "targets" for endorser peer objects in the Transaction proposal request'));
- }
-
- if(!request.chaincodeId) {
- logger.error('Missing chaincodeId in the Transaction proposal request');
- return Promise.reject(new Error('Missing chaincodeId in the Transaction proposal request'));
+ var errorMsg = null;
+ // args is not optional because we need for transaction to execute
+ if (request && !request.args) {
+ errorMsg = 'Missing "args" in Transaction proposal request';
+ } else {
+ errorMsg = Member._checkProposalRequest(request);
}
- // args is not optional because we need for transaction to execute
- if (!request.args) {
- logger.error('Missing arguments in Transaction proposal request');
- return Promise.reject(new Error('Missing arguments in Transaction proposal request'));
+ if(errorMsg) {
+ logger.error('Member.sendTransactionProposal error '+ errorMsg);
+ return Promise.reject(new Error(errorMsg));
}
var args = [];
@@ -470,13 +491,14 @@ var Member = class {
}
};
- let proposal = this._buildProposal(invokeSpec, request.chaincodeId);
- let signed_proposal = this._signProposal(proposal);
+ let header = Member._buildHeader(this._enrollment.certificate, request.chainId, request.chaincodeId, request.txId, request.nonce);
+ let proposal = this._buildProposal(invokeSpec, header);
+ let signed_proposal = this._signProposal(this._enrollment, proposal);
return Member._sendPeersProposal(request.targets, signed_proposal)
.then(
function(responses) {
- return Promise.resolve([responses,proposal]);
+ return Promise.resolve([responses, proposal, header]);
}
).catch(
function(err) {
@@ -532,26 +554,25 @@ var Member = class {
/**
* @private
*/
- static _buildHeader(creator, chaincode_id) {
+ static _buildHeader(creator, chain_id, chaincode_id, tx_id, nonce) {
let chainHeader = new _commonProto.ChainHeader();
chainHeader.setType(_commonProto.HeaderType.ENDORSER_TRANSACTION);
- chainHeader.setVersion(0); //TODO what should this be
+ chainHeader.setTxID(tx_id.toString());
+ chainHeader.setChainID(Buffer.from(chain_id));
if(chaincode_id) {
let chaincodeID = new _ccProto.ChaincodeID();
chaincodeID.setName(chaincode_id);
let headerExt = new _ccProposalProto.ChaincodeHeaderExtension();
headerExt.setChaincodeID(chaincodeID);
-// headerExt.setPayloadVisibility(TODO);
- chainHeader.setChainID(chaincodeID.toBuffer());
chainHeader.setExtension(headerExt.toBuffer());
}
let signatureHeader = new _commonProto.SignatureHeader();
signatureHeader.setCreator(Buffer.from(creator));
- signatureHeader.setNonce(crypto.randomBytes(sdkUtils.getConfigSetting('nonce-size', 24)));
+ signatureHeader.setNonce(nonce);
let header = new _commonProto.Header();
header.setSignatureHeader(signatureHeader);
@@ -564,7 +585,7 @@ var Member = class {
/**
* @private
*/
- _buildProposal(invokeSpec, chaincode_id) {
+ _buildProposal(invokeSpec, header) {
// construct the ChaincodeInvocationSpec
let cciSpec = new _ccProto.ChaincodeInvocationSpec();
cciSpec.setChaincodeSpec(invokeSpec);
@@ -572,9 +593,7 @@ var Member = class {
let cc_payload = new _ccProposalProto.ChaincodeProposalPayload();
cc_payload.setInput(cciSpec.toBuffer());
- //cc_payload.setTransient(n/a); // TODO application-level confidentiality related
-
- let header = Member._buildHeader(this._enrollment.certificate, chaincode_id);
+ //cc_payload.setTransient(null); // TODO application-level confidentiality related
// proposal -- will switch to building the proposal once the signProposal is used
let proposal = new _proposalProto.Proposal();
@@ -632,11 +651,11 @@ var Member = class {
/**
* @private
*/
- _signProposal(proposal) {
+ _signProposal(enrollment, proposal) {
let proposal_bytes = proposal.toBuffer();
// sign the proposal
- let sig = this._chain.cryptoPrimitives.sign(this._enrollment.privateKey, proposal_bytes);
- let signature = new Buffer(sig.toDER());
+ let sig = this._chain.cryptoPrimitives.sign(enrollment.privateKey, proposal_bytes);
+ let signature = Buffer.from(sig.toDER());
logger.debug('_signProposal - signature::'+JSON.stringify(signature));
@@ -704,6 +723,32 @@ var Member = class {
return JSON.stringify(state);
}
+
+ /*
+ * @private
+ */
+ static _checkProposalRequest(request) {
+ var errorMsg = null;
+
+ if(request) {
+ if(!request.chaincodeId) {
+ errorMsg = 'Missing "chaincodeId" parameter in the proposal request';
+ } else if(!request.chainId) {
+ errorMsg = 'Missing "chainId" parameter in the proposal request';
+ } else if(!request.targets) {
+ errorMsg = 'Missing "targets" parameter in the proposal request';
+ } else if(!request.txId) {
+ errorMsg = 'Missing "txId" parameter in the proposal request';
+ } else if(!request.chainId) {
+ errorMsg = 'Missing "chainId" parameter in the proposal request';
+ } else if(!request.nonce) {
+ errorMsg = 'Missing "nonce" parameter in the proposal request';
+ }
+ } else {
+ errorMsg = 'Missing input request object on the proposal request';
+ }
+ return errorMsg;
+ }
};
function toKeyValueStoreName(name) {
diff --git a/hfc/lib/protos/common/common.proto b/hfc/lib/protos/common/common.proto
index 1d16831e19..1484a3bb62 100644
--- a/hfc/lib/protos/common/common.proto
+++ b/hfc/lib/protos/common/common.proto
@@ -59,6 +59,14 @@ message ChainHeader {
// Identifier of the chain this message is bound for
bytes chainID = 4;
+ // An unique identifier that is used end-to-end.
+ // - set by higher layers such as end user or SDK
+ // - passed to the endorser (which will check for uniqueness)
+ // - as the header is passed along unchanged, it will be
+ // be retrieved by the committer (uniqueness check here as well)
+ // - to be stored in the ledger
+ string txID = 5;
+
// The epoch in which this header was generated, where epoch is defined based on block height
// Epoch in which the response has been generated. This field identifies a
// logical window of time. A proposal response is accepted by a peer only if
@@ -66,10 +74,10 @@ message ChainHeader {
// 1. the epoch specified in the message is the current epoch
// 2. this message has been only seen once during this epoch (i.e. it hasn't
// been replayed)
- uint64 epoch = 5;
+ uint64 epoch = 6;
// Extension that may be attached based on the header type
- bytes extension = 6;
+ bytes extension = 7;
}
message SignatureHeader {
diff --git a/hfc/lib/protos/peer/api.proto b/hfc/lib/protos/peer/api.proto
deleted file mode 100644
index 6fa87c3758..0000000000
--- a/hfc/lib/protos/peer/api.proto
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-Copyright IBM Corp. 2016 All Rights Reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-syntax = "proto3";
-
-package protos;
-
-import "fabric.proto";
-import "../google/protobuf/empty.proto";
-
-option go_package = "github.com/hyperledger/fabric/protos/peer";
-
-// Interface exported by the server.
-service Openchain {
-
- // GetBlockchainInfo returns information about the blockchain ledger such as
- // height, current block hash, and previous block hash.
- rpc GetBlockchainInfo(google.protobuf.Empty) returns (BlockchainInfo) {}
-
- // GetBlockByNumber returns the data contained within a specific block in the
- // blockchain. The genesis block is block zero.
- rpc GetBlockByNumber(BlockNumber) returns (Block) {}
-
- // GetBlockCount returns the current number of blocks in the blockchain data
- // structure.
- rpc GetBlockCount(google.protobuf.Empty) returns (BlockCount) {}
-
- // GetPeers returns a list of all peer nodes currently connected to the target
- // peer.
- rpc GetPeers(google.protobuf.Empty) returns (PeersMessage) {}
-}
-
-// Specifies the block number to be returned from the blockchain.
-message BlockNumber {
-
- uint64 number = 1;
-
-}
-
-// Specifies the current number of blocks in the blockchain.
-message BlockCount {
-
- uint64 count = 1;
-
-}
diff --git a/hfc/lib/protos/peer/chaincode.proto b/hfc/lib/protos/peer/chaincode.proto
index 18971a62dd..cc66e0cfda 100644
--- a/hfc/lib/protos/peer/chaincode.proto
+++ b/hfc/lib/protos/peer/chaincode.proto
@@ -106,20 +106,6 @@ message ChaincodeInvocationSpec {
string idGenerationAlg = 2;
}
-// This structure contain transaction data that we send to the chaincode
-// container shim and allow the chaincode to access through the shim interface.
-// TODO: Consider remove this message and just pass the transaction object
-// to the shim and/or allow the chaincode to query transactions.
-message ChaincodeSecurityContext {
- bytes callerCert = 1;
- bytes callerSign = 2;
- bytes payload = 3;
- bytes binding = 4;
- bytes metadata = 5;
- bytes parentMetadata = 6;
- google.protobuf.Timestamp txTimestamp = 7; // transaction timestamp
-}
-
message ChaincodeMessage {
enum Type {
@@ -135,22 +121,17 @@ message ChaincodeMessage {
PUT_STATE = 9;
DEL_STATE = 10;
INVOKE_CHAINCODE = 11;
- INVOKE_QUERY = 12;
RESPONSE = 13;
- QUERY = 14;
- QUERY_COMPLETED = 15;
- QUERY_ERROR = 16;
- RANGE_QUERY_STATE = 17;
- RANGE_QUERY_STATE_NEXT = 18;
- RANGE_QUERY_STATE_CLOSE = 19;
- KEEPALIVE = 20;
+ RANGE_QUERY_STATE = 14;
+ RANGE_QUERY_STATE_NEXT = 15;
+ RANGE_QUERY_STATE_CLOSE = 16;
+ KEEPALIVE = 17;
}
Type type = 1;
google.protobuf.Timestamp timestamp = 2;
bytes payload = 3;
string txid = 4;
- ChaincodeSecurityContext securityContext = 5;
//event emmited by chaincode. Used only with Init or Invoke.
// This event is then stored (currently)
diff --git a/hfc/lib/protos/peer/devops.proto b/hfc/lib/protos/peer/devops.proto
deleted file mode 100644
index e78fd462fd..0000000000
--- a/hfc/lib/protos/peer/devops.proto
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
-Copyright IBM Corp. 2016 All Rights Reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-syntax = "proto3";
-
-package protos;
-
-option go_package = "github.com/hyperledger/fabric/protos/peer";
-
-import "chaincode.proto";
-import "fabric.proto";
-
-// Interface exported by the server.
-service Devops {
- // Log in - passed Secret object and returns Response object, where
- // msg is the security context to be used in subsequent invocations
- rpc Login(Secret) returns (Response) {}
-
- // Build the chaincode package.
- rpc Build(ChaincodeSpec) returns (ChaincodeDeploymentSpec) {}
-
- // Deploy the chaincode package to the chain.
- rpc Deploy(ChaincodeSpec) returns (ChaincodeDeploymentSpec) {}
-
- // Invoke chaincode.
- rpc Invoke(ChaincodeInvocationSpec) returns (Response) {}
-
- // Query chaincode.
- rpc Query(ChaincodeInvocationSpec) returns (Response) {}
-
- // Retrieve a TCert.
- rpc EXP_GetApplicationTCert(Secret) returns (Response) {}
-
- // Prepare for performing a TX, which will return a binding that can later be used to sign and then execute a transaction.
- rpc EXP_PrepareForTx(Secret) returns (Response) {}
-
- // Prepare for performing a TX, which will return a binding that can later be used to sign and then execute a transaction.
- rpc EXP_ProduceSigma(SigmaInput) returns (Response) {}
-
- // Execute a transaction with a specific binding
- rpc EXP_ExecuteWithBinding(ExecuteWithBinding) returns (Response) {}
-}
-
-// Secret is a temporary object to establish security with the Devops.
-// A better solution using certificate will be introduced later
-message Secret {
- string enrollId = 1;
- string enrollSecret = 2;
-}
-
-message SigmaInput {
- Secret secret = 1;
- bytes appTCert = 2;
- bytes data = 3;
-}
-
-message ExecuteWithBinding {
- ChaincodeInvocationSpec chaincodeInvocationSpec = 1;
- bytes binding = 2;
-}
-
-message SigmaOutput {
- bytes tcert = 1;
- bytes sigma = 2;
- bytes asn1Encoding = 3;
-}
-
-message BuildResult {
-
- enum StatusCode {
- UNDEFINED = 0;
- SUCCESS = 1;
- FAILURE = 2;
- }
-
- StatusCode status = 1;
- string msg = 2;
- ChaincodeDeploymentSpec deploymentSpec = 3;
-}
-
-message TransactionRequest {
- string transactionUuid = 1;
-}
diff --git a/hfc/lib/protos/peer/events.proto b/hfc/lib/protos/peer/events.proto
index 9ce2ec59ea..29273e5100 100644
--- a/hfc/lib/protos/peer/events.proto
+++ b/hfc/lib/protos/peer/events.proto
@@ -17,7 +17,8 @@ limitations under the License.
syntax = "proto3";
import "chaincodeevent.proto";
-import "fabric.proto";
+import "fabric_transaction.proto";
+import "fabric_block.proto";
option go_package = "github.com/hyperledger/fabric/protos/peer";
@@ -81,7 +82,7 @@ message Event {
Register register = 1;
//producer events
- Block block = 2;
+ Block2 block = 2;
ChaincodeEvent chaincodeEvent = 3;
Rejection rejection = 4;
diff --git a/hfc/lib/protos/peer/fabric.proto b/hfc/lib/protos/peer/fabric.proto
index 528709a847..0d7ac13fdd 100644
--- a/hfc/lib/protos/peer/fabric.proto
+++ b/hfc/lib/protos/peer/fabric.proto
@@ -18,118 +18,6 @@ syntax = "proto3";
option go_package = "github.com/hyperledger/fabric/protos/peer";
package protos;
-import "chaincode.proto";
-import "chaincodeevent.proto";
-import "../google/protobuf/timestamp.proto";
-
-
-// Transaction defines a function call to a contract.
-// `args` is an array of type string so that the chaincode writer can choose
-// whatever format they wish for the arguments for their chaincode.
-// For example, they may wish to use JSON, XML, or a custom format.
-// TODO: Defined remaining fields.
-message Transaction {
- enum Type {
- UNDEFINED = 0;
- // deploy a chaincode to the network and call `Init` function
- CHAINCODE_DEPLOY = 1;
- // call a chaincode `Invoke` function as a transaction
- CHAINCODE_INVOKE = 2;
- // call a chaincode `query` function
- CHAINCODE_QUERY = 3;
- // terminate a chaincode; not implemented yet
- CHAINCODE_TERMINATE = 4;
- }
- Type type = 1;
- //store ChaincodeID as bytes so its encrypted value can be stored
- bytes chaincodeID = 2;
- bytes payload = 3;
- bytes metadata = 4;
- string txid = 5;
- google.protobuf.Timestamp timestamp = 6;
-
- ConfidentialityLevel confidentialityLevel = 7;
- string confidentialityProtocolVersion = 8;
- bytes nonce = 9;
-
- bytes toValidators = 10;
- bytes cert = 11;
- bytes signature = 12;
-}
-
-// TransactionBlock carries a batch of transactions.
-message TransactionBlock {
- repeated Transaction transactions = 1;
-}
-
-// TransactionResult contains the return value of a transaction. It does
-// not track potential state changes that were a result of the transaction.
-// txid - The unique identifier of this transaction.
-// result - The return value of the transaction.
-// errorCode - An error code. 5xx will be logged as a failure in the dashboard.
-// error - An error string for logging an issue.
-// chaincodeEvent - any event emitted by a transaction
-message TransactionResult {
- string txid = 1;
- bytes result = 2;
- uint32 errorCode = 3;
- string error = 4;
- ChaincodeEvent chaincodeEvent = 5;
-}
-
-// Block carries The data that describes a block in the blockchain.
-// version - Version used to track any protocol changes.
-// timestamp - The time at which the block or transaction order
-// was proposed. This may not be used by all consensus modules.
-// transactions - The ordered list of transactions in the block.
-// stateHash - The state hash after running transactions in this block.
-// previousBlockHash - The hash of the previous block in the chain.
-// consensusMetadata - Consensus modules may optionally store any
-// additional metadata in this field.
-// nonHashData - Data stored with the block, but not included in the blocks
-// hash. This allows this data to be different per peer or discarded without
-// impacting the blockchain.
-message Block {
- uint32 version = 1;
- google.protobuf.Timestamp timestamp = 2;
- repeated Transaction transactions = 3;
- bytes stateHash = 4;
- bytes previousBlockHash = 5;
- bytes consensusMetadata = 6;
- NonHashData nonHashData = 7;
-}
-
-// Contains information about the blockchain ledger such as height, current
-// block hash, and previous block hash.
-message BlockchainInfo {
-
- uint64 height = 1;
- bytes currentBlockHash = 2;
- bytes previousBlockHash = 3;
-
-}
-
-// NonHashData is data that is recorded on the block, but not included in
-// the block hash when verifying the blockchain.
-// localLedgerCommitTimestamp - The time at which the block was added
-// to the ledger on the local peer.
-// chaincodeEvent - is an array ChaincodeEvents, one per transaction in the
-// block
-message NonHashData {
- google.protobuf.Timestamp localLedgerCommitTimestamp = 1;
- repeated ChaincodeEvent chaincodeEvents = 2;
-}
-
-// Interface exported by the server.
-service Peer {
- // Accepts a stream of Message during chat session, while receiving
- // other Message (e.g. from other peers).
- rpc Chat(stream Message) returns (stream Message) {}
-
- // Process a transaction from a remote source.
- rpc ProcessTransaction(Transaction) returns (Response) {}
-
-}
message PeerAddress {
string host = 1;
@@ -160,106 +48,12 @@ message PeersAddresses {
repeated string addresses = 1;
}
-message HelloMessage {
- PeerEndpoint peerEndpoint = 1;
- BlockchainInfo blockchainInfo = 2;
-}
-
-message Message {
- enum Type {
- UNDEFINED = 0;
-
- DISC_HELLO = 1;
- DISC_DISCONNECT = 2;
- DISC_GET_PEERS = 3;
- DISC_PEERS = 4;
- DISC_NEWMSG = 5;
-
- CHAIN_TRANSACTION = 6;
-
- SYNC_GET_BLOCKS = 11;
- SYNC_BLOCKS = 12;
- SYNC_BLOCK_ADDED = 13;
-
- SYNC_STATE_GET_SNAPSHOT = 14;
- SYNC_STATE_SNAPSHOT = 15;
- SYNC_STATE_GET_DELTAS = 16;
- SYNC_STATE_DELTAS = 17;
-
- RESPONSE = 20;
- CONSENSUS = 21;
- }
- Type type = 1;
- google.protobuf.Timestamp timestamp = 2;
- bytes payload = 3;
- bytes signature = 4;
-}
-
-message Response {
- enum StatusCode {
- UNDEFINED = 0;
- SUCCESS = 200;
- FAILURE = 500;
- }
- StatusCode status = 1;
- bytes msg = 2;
-}
-
-// BlockState is the payload of Message.SYNC_BLOCK_ADDED. When a VP
-// commits a new block to the ledger, it will notify its connected NVPs of the
-// block and the delta state. The NVP may call the ledger APIs to apply the
-// block and the delta state to its ledger if the block's previousBlockHash
-// equals to the NVP's current block hash
-message BlockState {
- Block block = 1;
- bytes stateDelta = 2;
-}
-
-// SyncBlockRange is the payload of Message.SYNC_GET_BLOCKS, where
-// start and end indicate the starting and ending blocks inclusively. The order
-// in which blocks are returned is defined by the start and end values. For
-// example, if start=3 and end=5, the order of blocks will be 3, 4, 5.
-// If start=5 and end=3, the order will be 5, 4, 3.
-message SyncBlockRange {
- uint64 correlationId = 1;
- uint64 start = 2;
- uint64 end = 3;
-}
-
-// SyncBlocks is the payload of Message.SYNC_BLOCKS, where the range
-// indicates the blocks responded to the request SYNC_GET_BLOCKS
-message SyncBlocks {
- SyncBlockRange range = 1;
- repeated Block blocks = 2;
-}
-
-// SyncSnapshotRequest Payload for the penchainMessage.SYNC_GET_SNAPSHOT message.
-message SyncStateSnapshotRequest {
- uint64 correlationId = 1;
-}
-
-// SyncStateSnapshot is the payload of Message.SYNC_SNAPSHOT, which is a response
-// to penchainMessage.SYNC_GET_SNAPSHOT. It contains the snapshot or a chunk of the
-// snapshot on stream, and in which case, the sequence indicate the order
-// starting at 0. The terminating message will have len(delta) == 0.
-message SyncStateSnapshot {
- bytes delta = 1;
- uint64 sequence = 2;
- uint64 blockNumber = 3;
- SyncStateSnapshotRequest request = 4;
-}
+// Contains information about the blockchain ledger such as height, current
+// block hash, and previous block hash.
+message BlockchainInfo {
-// SyncStateDeltasRequest is the payload of Message.SYNC_GET_STATE.
-// blockNumber indicates the block number for the delta which is being
-// requested. If no payload is included with SYNC_GET_STATE, it represents
-// a request for a snapshot of the current state.
-message SyncStateDeltasRequest {
- SyncBlockRange range = 1;
-}
+ uint64 height = 1;
+ bytes currentBlockHash = 2;
+ bytes previousBlockHash = 3;
-// SyncStateDeltas is the payload of the Message.SYNC_STATE in response to
-// the Message.SYNC_GET_STATE message.
-message SyncStateDeltas {
- SyncBlockRange range = 1;
- repeated bytes deltas = 2;
}
diff --git a/hfc/lib/protos/peer/fabric_message.proto b/hfc/lib/protos/peer/fabric_message.proto
index 2b12d4935e..9bbcfe6292 100644
--- a/hfc/lib/protos/peer/fabric_message.proto
+++ b/hfc/lib/protos/peer/fabric_message.proto
@@ -20,8 +20,8 @@ option go_package = "github.com/hyperledger/fabric/protos/peer";
package protos;
-// A Message2 encapsulates a payload of the indicated type in this message.
-message Message2 {
+// A Message encapsulates a payload of the indicated type in this message.
+message Message {
enum Type {
diff --git a/hfc/lib/protos/peer/fabric_proposal_response.proto b/hfc/lib/protos/peer/fabric_proposal_response.proto
index 3ba30f9a2b..1353e64dfa 100644
--- a/hfc/lib/protos/peer/fabric_proposal_response.proto
+++ b/hfc/lib/protos/peer/fabric_proposal_response.proto
@@ -41,7 +41,7 @@ message ProposalResponse {
// A response message indicating whether the
// endorsement of the action was successful
- Response2 response = 4;
+ Response response = 4;
// The payload of response. It is the bytes of ProposalResponsePayload
bytes payload = 5;
@@ -53,7 +53,7 @@ message ProposalResponse {
// A response with a representation similar to an HTTP response that can
// be used within another message.
-message Response2 {
+message Response {
// A status code that should follow the HTTP status codes.
int32 status = 1;
diff --git a/hfc/lib/protos/peer/fabric_transaction.proto b/hfc/lib/protos/peer/fabric_transaction.proto
index 75d3bacc78..a2621831eb 100644
--- a/hfc/lib/protos/peer/fabric_transaction.proto
+++ b/hfc/lib/protos/peer/fabric_transaction.proto
@@ -43,7 +43,7 @@ message InvalidTransaction {
TxIdAlreadyExists = 0;
RWConflictDuringCommit = 1;
}
- Transaction2 transaction = 1;
+ Transaction transaction = 1;
Cause cause = 2;
}
@@ -59,7 +59,7 @@ message InvalidTransaction {
// (ProposalResponsePayload) with one signature per Endorser. Any number of
// independent proposals (and their action) might be included in a transaction
// to ensure that they are treated atomically.
-message Transaction2 {
+message Transaction {
// Version indicates message protocol version.
int32 version = 1;
diff --git a/hfc/lib/protos/peer/fabric_transaction_header.proto b/hfc/lib/protos/peer/fabric_transaction_header.proto
deleted file mode 100644
index 4a1b30435a..0000000000
--- a/hfc/lib/protos/peer/fabric_transaction_header.proto
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
-Copyright IBM Corp. 2016 All Rights Reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-syntax = "proto3";
-
-option go_package = "github.com/hyperledger/fabric/protos/peer";
-
-package protos;
-
-import "../google/protobuf/timestamp.proto";
-
-// A Header contains fields that are common to all proposals and all
-// transactions, no matter their type. It can include also type-dependant
-// fields by using the 'extensions' field. This header is on purpose the same
-// header for proposals (a request to do "something" on the ledger) and a
-// transaction (the endorsed actions following from some request).
-// Furthermore, a proposal, its endorsements and the resulting transaction are
-// linked together by this message, as follows
-// 1. a Proposal contains a Header
-// 2. the hash of the Header of a proposal is included in the proposal response
-// generated by each endorser as a result of that proposal
-// 3. a TransactionAction contains both i) the *same* Header (byte-by-byte) of
-// the corresponsing Proposal and ii) the hash of the Header in each of the
-// endorsed actions
-message Header {
-
- enum Type {
- UNDEFINED = 0;
- CHAINCODE = 1;
- }
-
- // Version indicates message protocol version
- int32 version = 1;
-
- // Timestamp is the local time when the message was created
- // by the sender
- google.protobuf.Timestamp timestamp = 2;
-
- // Type of the transaction
- Type type = 3;
-
- // Creator of the header (and encapsulating message). This is usually a tcert
- // or ecert identifying the entity who submits the proposal/transaction. The
- // creator identifies the signer of
- // 1. a proposal (if this is the header of a Proposal message)
- // 2. a transaction (if this is the header of a TransactionAction message)
- bytes creator = 4;
-
- // Arbitrary number that may only be used once. This ensures the hash of
- // the proposal is unique and may be used in replay detection
- bytes nonce = 5;
-
- // Identifier of the chain this header targets to
- bytes chainID = 6;
-
- // Extensions is used to include type-dependant fields
- bytes extensions = 7;
-}
diff --git a/hfc/lib/utils.js b/hfc/lib/utils.js
index b74a96aa93..816dbafb76 100644
--- a/hfc/lib/utils.js
+++ b/hfc/lib/utils.js
@@ -24,6 +24,7 @@ var zlib = require('zlib');
var urlParser = require('url');
var winston = require('winston');
var Config = require('./Config.js');
+var crypto = require('crypto');
//
// Load required crypto stuff.
@@ -366,3 +367,32 @@ module.exports.existsSync = function(absolutePath /*string*/) {
}
};
+// utility function to build an unique transaction id
+// The request object may contain values that could be
+// used to help generate the result value
+module.exports.buildTransactionID = function(request /*object*/) {
+ var length = 10;
+ if(request && request.length) {
+ length = request.length;
+ }
+ var value = crypto.randomBytes(10); //TODO how should we really generate this value
+ return value;
+};
+
+// utility function to create a random number of
+// the specified length.
+module.exports.getNonce = function(length) {
+ if(length) {
+ if(Number.isInteger(length)) {
+ // good, it is a number
+ } else {
+ throw new Error('Parameter must be an integer');
+ }
+ } else {
+ length = this.getConfigSetting('nonce-size', 24);
+ }
+
+ var value = crypto.randomBytes(length);
+ return value;
+};
+
diff --git a/test/fixtures/docker-compose.yml b/test/fixtures/docker-compose.yml
index 3f68b91fc2..86e5cf8327 100644
--- a/test/fixtures/docker-compose.yml
+++ b/test/fixtures/docker-compose.yml
@@ -33,24 +33,24 @@ vp0:
ports:
- 7051:7051
-vp1:
- image: hyperledger/fabric-peer
- environment:
- - CORE_PEER_ADDRESSAUTODETECT=true
- - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- - CORE_LOGGING_LEVEL=DEBUG
- - CORE_PEER_NETWORKID=${CORE_PEER_NETWORKID}
- - CORE_NEXT=true
- - CORE_PEER_ENDORSER_ENABLED=true
- - CORE_PEER_ID=vp1
- - CORE_PEER_PROFILE_ENABLED=true
- - CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050
- - CORE_PEER_DISCOVERY_ROOTNODE=vp0:7051
- volumes:
- - /var/run/:/host/var/run/
- command: peer node start
- links:
- - orderer
- - vp0
- ports:
- - 7056:7051
+# vp1:
+# image: hyperledger/fabric-peer
+# environment:
+# - CORE_PEER_ADDRESSAUTODETECT=true
+# - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
+# - CORE_LOGGING_LEVEL=DEBUG
+# - CORE_PEER_NETWORKID=${CORE_PEER_NETWORKID}
+# - CORE_NEXT=true
+# - CORE_PEER_ENDORSER_ENABLED=true
+# - CORE_PEER_ID=vp1
+# - CORE_PEER_PROFILE_ENABLED=true
+# - CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050
+# - CORE_PEER_DISCOVERY_ROOTNODE=vp0:7051
+# volumes:
+# - /var/run/:/host/var/run/
+# command: peer node start
+# links:
+# - orderer
+# - vp0
+# ports:
+# - 7056:7051
diff --git a/test/unit/end-to-end.js b/test/unit/end-to-end.js
index a04e088902..f91736bd42 100644
--- a/test/unit/end-to-end.js
+++ b/test/unit/end-to-end.js
@@ -31,7 +31,10 @@ var utils = require('hfc/lib/utils.js');
var chain = hfc.newChain('testChain-e2e');
var webUser;
-var chaincode_id = 'mycc1';
+var chaincode_id = 'mycc2';
+var chain_id = '**TEST_CHAINID**';
+var tx_id = null;
+var nonce = null;
testUtil.setupChaincodeDeploy();
@@ -52,14 +55,19 @@ test('End-to-end flow of chaincode deploy, transaction invocation, and query', f
function(admin) {
t.pass('Successfully enrolled user \'admin\'');
webUser = admin;
+ tx_id = hfc.buildTransactionID({length:12});
+ nonce = hfc.getNonce();
// send proposal to endorser
var request = {
- targets: [hfc.getPeer('grpc://localhost:7051'), hfc.getPeer('grpc://localhost:7056')],
+ targets: [hfc.getPeer('grpc://localhost:7051')], // hfc.getPeer('grpc://localhost:7056')],
chaincodePath: testUtil.CHAINCODE_PATH,
chaincodeId: chaincode_id,
fcn: 'init',
args: ['a', '100', 'b', '200'],
+ chainId: chain_id,
+ txId: tx_id,
+ nonce: nonce,
'dockerfile-contents' :
'from hyperledger/fabric-ccenv\n' +
'COPY . $GOPATH/src/build-chaincode/\n' +
@@ -78,9 +86,15 @@ test('End-to-end flow of chaincode deploy, transaction invocation, and query', f
var proposalResponses = results[0];
//console.log('proposalResponses:'+JSON.stringify(proposalResponses));
var proposal = results[1];
+ var header = results[2];
if (proposalResponses && proposalResponses[0].response && proposalResponses[0].response.status === 200) {
t.pass(util.format('Successfully sent Proposal and received ProposalResponse: Status - %s, message - "%s", metadata - "%s", endorsement signature: %s', proposalResponses[0].response.status, proposalResponses[0].response.message, proposalResponses[0].response.payload, proposalResponses[0].endorsement.signature));
- return webUser.sendTransaction(proposalResponses, proposal);
+ var request = {
+ proposalResponses: proposalResponses,
+ proposal: proposal,
+ header: header
+ };
+ return webUser.sendTransaction(request);
} else {
t.fail('Failed to send Proposal or receive valid response. Response null or status is not 200. exiting...');
t.end();
@@ -108,12 +122,17 @@ test('End-to-end flow of chaincode deploy, transaction invocation, and query', f
}
).then(
function() {
+ tx_id = hfc.buildTransactionID({length:12});
+ nonce = hfc.getNonce();
// send proposal to endorser
var request = {
- targets: [hfc.getPeer('grpc://localhost:7051'), hfc.getPeer('grpc://localhost:7056')],
+ targets: [hfc.getPeer('grpc://localhost:7051')], // hfc.getPeer('grpc://localhost:7056')],
chaincodeId : chaincode_id,
fcn: 'invoke',
- args: ['move', 'a', 'b','100']
+ args: ['move', 'a', 'b','100'],
+ chainId: chain_id,
+ txId: tx_id,
+ nonce: nonce
};
return webUser.sendTransactionProposal(request);
},
@@ -125,9 +144,15 @@ test('End-to-end flow of chaincode deploy, transaction invocation, and query', f
function(results) {
var proposalResponses = results[0];
var proposal = results[1];
+ var header = results[2];
if (proposalResponses[0].response.status === 200) {
- t.pass('Successfully obtained transaction endorsement.' + JSON.stringify(proposalResponses));
- return webUser.sendTransaction(proposalResponses, proposal);
+ t.pass('Successfully obtained transaction endorsement.'); // + JSON.stringify(proposalResponses));
+ var request = {
+ proposalResponses: proposalResponses,
+ proposal: proposal,
+ header: header
+ };
+ return webUser.sendTransaction(request);
} else {
t.fail('Failed to obtain transaction endorsement. Error code: ' + status);
t.end();
@@ -156,8 +181,11 @@ test('End-to-end flow of chaincode deploy, transaction invocation, and query', f
function() {
// send query
var request = {
- targets: [hfc.getPeer('grpc://localhost:7051'), hfc.getPeer('grpc://localhost:7056')],
+ targets: [hfc.getPeer('grpc://localhost:7051')], // hfc.getPeer('grpc://localhost:7056')],
chaincodeId : chaincode_id,
+ chainId: chain_id,
+ txId: hfc.buildTransactionID(),
+ nonce: hfc.getNonce(),
fcn: 'invoke',
args: ['query','b']
};
diff --git a/test/unit/headless-tests.js b/test/unit/headless-tests.js
index 44e637ac05..b533bbc441 100644
--- a/test/unit/headless-tests.js
+++ b/test/unit/headless-tests.js
@@ -567,13 +567,17 @@ test('\n\n ** Member sendDeploymentProposal() tests **\n\n', function (t) {
var m = new Member('does not matter', _chain);
var p1 = m.sendDeploymentProposal({
- chaincodePath: 'blah',
+ targets: [hfc.getPeer('grpc://localhost:7051')],
chaincodeId: 'blah',
- fcn: 'init'
+ fcn: 'init',
+ args: ['a', '100', 'b', '200'],
+ chainId: 'blah',
+ txId: 'blah',
+ nonce: 'blah'
}).then(function () {
t.fail('Should not have been able to resolve the promise because of missing "peer" parameter');
}).catch(function (err) {
- if (err.message === 'Missing "targets" for the endorsing peer objects in the Deployment proposal request') {
+ if (err.message.indexOf('Missing chaincodePath parameter in Deployment proposal request') >= 0) {
t.pass('Successfully caught missing peer error');
} else {
t.fail('Failed to catch the missing peer error. Error: ' + err.stack ? err.stask : err);
@@ -581,32 +585,106 @@ test('\n\n ** Member sendDeploymentProposal() tests **\n\n', function (t) {
});
var p2 = m.sendDeploymentProposal({
- endorserUrl: 'blah',
- fcn: 'init'
+ targets: [hfc.getPeer('grpc://localhost:7051')],
+ chaincodePath: 'blah',
+ chaincodeId: 'blah',
+ fcn: 'init',
+ args: ['a', '100', 'b', '200'],
+ txId: 'blah',
+ nonce: 'blah'
}).then(function () {
- t.fail('Should not have been able to resolve the promise because of missing "chaincodePath" parameter');
+ t.fail('Should not have been able to resolve the promise because of missing "chainId" parameter');
}).catch(function (err) {
- if (err.message === 'Missing chaincodePath in Deployment proposal request') {
- t.pass('Successfully caught missing chaincodePath error');
+ if (err.message.indexOf('Missing "chainId" parameter in the proposal request') >= 0) {
+ t.pass('Successfully caught missing chainId error');
} else {
- t.fail('Failed to catch the missing chaincodePath error. Error: ' + err.stack ? err.stask : err);
+ t.fail('Failed to catch the missing chainId error. Error: ' + err.stack ? err.stask : err);
}
});
var p3 = m.sendDeploymentProposal({
+ targets: [hfc.getPeer('grpc://localhost:7051')],
chaincodePath: 'blah',
- fcn: 'init'
+ chainId: 'blah',
+ fcn: 'init',
+ args: ['a', '100', 'b', '200'],
+ txId: 'blah',
+ nonce: 'blah'
}).then(function () {
t.fail('Should not have been able to resolve the promise because of missing "chaincodeId" parameter');
}).catch(function (err) {
- if (err.message === 'Missing chaincodeId in the Deployment proposal request') {
+ if (err.message.indexOf('Missing "chaincodeId" parameter in the proposal request') >= 0) {
t.pass('Successfully caught missing chaincodeId error');
} else {
t.fail('Failed to catch the missing chaincodeId error. Error: ' + err.stack ? err.stask : err);
}
});
- Promise.all([p1, p2, p3])
+ var p4 = m.sendDeploymentProposal({
+ chaincodePath: 'blah',
+ chaincodeId: 'blah',
+ chainId: 'blah',
+ fcn: 'init',
+ args: ['a', '100', 'b', '200'],
+ txId: 'blah',
+ nonce: 'blah'
+ }).then(function () {
+ t.fail('Should not have been able to resolve the promise because of missing "targets" parameter');
+ }).catch(function (err) {
+ if (err.message.indexOf('Missing "targets" parameter in the proposal request') >= 0) {
+ t.pass('Successfully caught missing targets error');
+ } else {
+ t.fail('Failed to catch the missing targets error. Error: ' + err.stack ? err.stask : err);
+ }
+ });
+
+ var p5 = m.sendDeploymentProposal({
+ targets: [hfc.getPeer('grpc://localhost:7051')],
+ chaincodePath: 'blah',
+ chaincodeId: 'blah',
+ chainId: 'blah',
+ fcn: 'init',
+ args: ['a', '100', 'b', '200'],
+ nonce: 'blah'
+ }).then(function () {
+ t.fail('Should not have been able to resolve the promise because of missing "txId" parameter');
+ }).catch(function (err) {
+ if (err.message.indexOf('Missing "txId" parameter in the proposal request') >= 0) {
+ t.pass('Successfully caught missing txId error');
+ } else {
+ t.fail('Failed to catch the missing txId error. Error: ' + err.stack ? err.stask : err);
+ }
+ });
+
+ var p6 = m.sendDeploymentProposal({
+ targets: [hfc.getPeer('grpc://localhost:7051')],
+ chaincodePath: 'blah',
+ chaincodeId: 'blah',
+ chainId: 'blah',
+ fcn: 'init',
+ args: ['a', '100', 'b', '200'],
+ txId: 'blah'
+ }).then(function () {
+ t.fail('Should not have been able to resolve the promise because of missing "nonce" parameter');
+ }).catch(function (err) {
+ if (err.message.indexOf('Missing "nonce" parameter in the proposal request') >= 0) {
+ t.pass('Successfully caught missing nonce error');
+ } else {
+ t.fail('Failed to catch the missing nonce error. Error: ' + err.stack ? err.stask : err);
+ }
+ });
+
+ var p7 = m.sendDeploymentProposal().then(function () {
+ t.fail('Should not have been able to resolve the promise because of missing request parameter');
+ }).catch(function (err) {
+ if (err.message.indexOf('Missing input request object on the proposal request') >= 0) {
+ t.pass('Successfully caught missing request error');
+ } else {
+ t.fail('Failed to catch the missing request error. Error: ' + err.stack ? err.stask : err);
+ }
+ });
+
+ Promise.all([p1, p2, p3, p4, p6, p7])
.then(
function (data) {
t.end();
@@ -623,61 +701,118 @@ test('\n\n ** Member sendTransactionProposal() tests **\n\n', function (t) {
var m = new Member('does not matter', _chain);
var p1 = m.sendTransactionProposal({
- chaincodeId: 'someid'
+ targets: [hfc.getPeer('grpc://localhost:7051')],
+ chaincodeId : 'blah',
+ fcn: 'invoke',
+ chainId: 'blah',
+ txId: 'blah',
+ nonce: 'blah'
}).then(function () {
- t.fail('Should not have been able to resolve the promise because of missing "targets" parameter');
- }, function (err) {
- if (err.message === 'Missing "targets" for endorser peer objects in the Transaction proposal request') {
+ t.fail('Should not have been able to resolve the promise because of missing "args" parameter');
+ }).catch(function (err) {
+ if (err.message.indexOf('Missing "targets" for endorser peer objects in the Transaction proposal request')) {
t.pass('Successfully caught missing targets error');
} else {
t.fail('Failed to catch the missing targets error. Error: ' + err.stack ? err.stask : err);
}
+ });
+
+ var p2 = m.sendTransactionProposal({
+ targets: [hfc.getPeer('grpc://localhost:7051')],
+ chaincodeId: 'blah',
+ fcn: 'init',
+ args: ['a', '100', 'b', '200'],
+ txId: 'blah',
+ nonce: 'blah'
+ }).then(function () {
+ t.fail('Should not have been able to resolve the promise because of missing "chainId" parameter');
}).catch(function (err) {
- if (err.message === 'Missing "targets" for endorser peer objects in the Transaction proposal request') {
- t.pass('Successfully caught missing targets error');
+ if (err.message.indexOf('Missing "chainId" parameter in the proposal request') >= 0) {
+ t.pass('Successfully caught missing chainId error');
} else {
- t.fail('Failed to catch the missing targets error. Error: ' + err.stack ? err.stask : err);
+ t.fail('Failed to catch the missing chainId error. Error: ' + err.stack ? err.stask : err);
}
});
- var p2 = m.sendTransactionProposal({
- targets: [hfc.getPeer('grpc://somehost.com:9000')]
+ var p3 = m.sendTransactionProposal({
+ targets: [hfc.getPeer('grpc://localhost:7051')],
+ chainId: 'blah',
+ fcn: 'init',
+ args: ['a', '100', 'b', '200'],
+ txId: 'blah',
+ nonce: 'blah'
}).then(function () {
- t.fail('Should not have been able to resolve the promise because of missing "chaincodePath" parameter');
- }, function (err) {
- if (err.message === 'Missing chaincodeId in the Transaction proposal request') {
- t.pass('Successfully caught missing chaincodeid error');
+ t.fail('Should not have been able to resolve the promise because of missing "chaincodeId" parameter');
+ }).catch(function (err) {
+ if (err.message.indexOf('Missing "chaincodeId" parameter in the proposal request') >= 0) {
+ t.pass('Successfully caught missing chaincodeId error');
} else {
- t.fail('Failed to catch the missing chaincodeid error. Error: ' + err.stack ? err.stask : err);
+ t.fail('Failed to catch the missing chaincodeId error. Error: ' + err.stack ? err.stask : err);
}
+ });
+
+ var p4 = m.sendTransactionProposal({
+ chaincodeId: 'blah',
+ chainId: 'blah',
+ fcn: 'init',
+ args: ['a', '100', 'b', '200'],
+ txId: 'blah',
+ nonce: 'blah'
+ }).then(function () {
+ t.fail('Should not have been able to resolve the promise because of missing "targets" parameter');
}).catch(function (err) {
- if (err.message === 'Missing chaincode ID in the Transaction proposal request') {
- t.pass('Successfully caught missing chaincodeid error');
+ if (err.message.indexOf('Missing "targets" parameter in the proposal request') >= 0) {
+ t.pass('Successfully caught missing targets error');
} else {
- t.fail('Failed to catch the missing chaincodeid error. Error: ' + err.stack ? err.stask : err);
+ t.fail('Failed to catch the missing targets error. Error: ' + err.stack ? err.stask : err);
}
});
- var p3 = m.sendTransactionProposal({
- targets: [hfc.getPeer('grpc://somehost.com:9000')],
- chaincodeId: 'someid'
+ var p5 = m.sendTransactionProposal({
+ targets: [hfc.getPeer('grpc://localhost:7051')],
+ chaincodeId: 'blah',
+ chainId: 'blah',
+ fcn: 'init',
+ args: ['a', '100', 'b', '200'],
+ nonce: 'blah'
}).then(function () {
- t.fail('Should not have been able to resolve the promise because of missing "chaincodePath" parameter');
- }, function (err) {
- if (err.message === 'Missing arguments in Transaction proposal request') {
- t.pass('Successfully caught missing args error');
+ t.fail('Should not have been able to resolve the promise because of missing "txId" parameter');
+ }).catch(function (err) {
+ if (err.message.indexOf('Missing "txId" parameter in the proposal request') >= 0) {
+ t.pass('Successfully caught missing txId error');
} else {
- t.fail('Failed to catch the missing args error. Error: ' + err.stack ? err.stask : err);
+ t.fail('Failed to catch the missing txId error. Error: ' + err.stack ? err.stask : err);
}
+ });
+
+ var p6 = m.sendTransactionProposal({
+ targets: [hfc.getPeer('grpc://localhost:7051')],
+ chaincodeId: 'blah',
+ chainId: 'blah',
+ fcn: 'init',
+ args: ['a', '100', 'b', '200'],
+ txId: 'blah'
+ }).then(function () {
+ t.fail('Should not have been able to resolve the promise because of missing "nonce" parameter');
+ }).catch(function (err) {
+ if (err.message.indexOf('Missing "nonce" parameter in the proposal request') >= 0) {
+ t.pass('Successfully caught missing nonce error');
+ } else {
+ t.fail('Failed to catch the missing nonce error. Error: ' + err.stack ? err.stask : err);
+ }
+ });
+
+ var p7 = m.sendTransactionProposal().then(function () {
+ t.fail('Should not have been able to resolve the promise because of missing request parameter');
}).catch(function (err) {
- if (err.message === 'Missing arguments in Transaction proposal request') {
- t.pass('Successfully caught missing args error');
+ if (err.message.indexOf('Missing input request object on the proposal request') >= 0) {
+ t.pass('Successfully caught missing request error');
} else {
- t.fail('Failed to catch the missing args error. Error: ' + err.stack ? err.stask : err);
+ t.fail('Failed to catch the missing request error. Error: ' + err.stack ? err.stask : err);
}
});
- Promise.all([p1, p2, p3])
+ Promise.all([p1, p2, p3, p4, p5, p6, p7])
.then(
function (data) {
t.end();
@@ -694,61 +829,118 @@ test('\n\n ** Member queryByChaincode() tests **\n\n', function (t) {
var m = new Member('does not matter', _chain);
var p1 = m.queryByChaincode({
- chaincodeId: 'someid'
+ targets: [hfc.getPeer('grpc://localhost:7051')],
+ chaincodeId : 'blah',
+ fcn: 'invoke',
+ chainId: 'blah',
+ txId: 'blah',
+ nonce: 'blah'
}).then(function () {
- t.fail('Should not have been able to resolve the promise because of missing "targets" parameter');
- }, function (err) {
- if (err.message === 'Missing "targets" for endorser peer objects in the Transaction proposal request') {
+ t.fail('Should not have been able to resolve the promise because of missing "args" parameter');
+ }).catch(function (err) {
+ if (err.message.indexOf('Missing "targets" for endorser peer objects in the Transaction proposal request')) {
t.pass('Successfully caught missing targets error');
} else {
t.fail('Failed to catch the missing targets error. Error: ' + err.stack ? err.stask : err);
}
+ });
+
+ var p2 = m.queryByChaincode({
+ targets: [hfc.getPeer('grpc://localhost:7051')],
+ chaincodeId: 'blah',
+ fcn: 'init',
+ args: ['a', '100', 'b', '200'],
+ txId: 'blah',
+ nonce: 'blah'
+ }).then(function () {
+ t.fail('Should not have been able to resolve the promise because of missing "chainId" parameter');
}).catch(function (err) {
- if (err.message === 'Missing "targets" for endorser peer objects in the Transaction proposal request') {
- t.pass('Successfully caught missing targets error');
+ if (err.message.indexOf('Missing "chainId" parameter in the proposal request') >= 0) {
+ t.pass('Successfully caught missing chainId error');
} else {
- t.fail('Failed to catch the missing targets error. Error: ' + err.stack ? err.stask : err);
+ t.fail('Failed to catch the missing chainId error. Error: ' + err.stack ? err.stask : err);
}
});
- var p2 = m.queryByChaincode({
- targets: [hfc.getPeer('grpc://somehost.com:9000')]
+ var p3 = m.queryByChaincode({
+ targets: [hfc.getPeer('grpc://localhost:7051')],
+ chainId: 'blah',
+ fcn: 'init',
+ args: ['a', '100', 'b', '200'],
+ txId: 'blah',
+ nonce: 'blah'
}).then(function () {
- t.fail('Should not have been able to resolve the promise because of missing "chaincodePath" parameter');
- }, function (err) {
- if (err.message === 'Missing chaincodeId in the Transaction proposal request') {
- t.pass('Successfully caught missing chaincodeid error');
+ t.fail('Should not have been able to resolve the promise because of missing "chaincodeId" parameter');
+ }).catch(function (err) {
+ if (err.message.indexOf('Missing "chaincodeId" parameter in the proposal request') >= 0) {
+ t.pass('Successfully caught missing chaincodeId error');
} else {
- t.fail('Failed to catch the missing chaincodeid error. Error: ' + err.stack ? err.stask : err);
+ t.fail('Failed to catch the missing chaincodeId error. Error: ' + err.stack ? err.stask : err);
}
+ });
+
+ var p4 = m.queryByChaincode({
+ chaincodeId: 'blah',
+ chainId: 'blah',
+ fcn: 'init',
+ args: ['a', '100', 'b', '200'],
+ txId: 'blah',
+ nonce: 'blah'
+ }).then(function () {
+ t.fail('Should not have been able to resolve the promise because of missing "targets" parameter');
}).catch(function (err) {
- if (err.message === 'Missing chaincode ID in the Transaction proposal request') {
- t.pass('Successfully caught missing chaincodeid error');
+ if (err.message.indexOf('Missing "targets" parameter in the proposal request') >= 0) {
+ t.pass('Successfully caught missing targets error');
} else {
- t.fail('Failed to catch the missing chaincodeid error. Error: ' + err.stack ? err.stask : err);
+ t.fail('Failed to catch the missing targets error. Error: ' + err.stack ? err.stask : err);
}
});
- var p3 = m.queryByChaincode({
- targets: [hfc.getPeer('grpc://somehost.com:9000')],
- chaincodeId: 'someid'
+ var p5 = m.queryByChaincode({
+ targets: [hfc.getPeer('grpc://localhost:7051')],
+ chaincodeId: 'blah',
+ chainId: 'blah',
+ fcn: 'init',
+ args: ['a', '100', 'b', '200'],
+ nonce: 'blah'
}).then(function () {
- t.fail('Should not have been able to resolve the promise because of missing "chaincodePath" parameter');
- }, function (err) {
- if (err.message === 'Missing arguments in Transaction proposal request') {
- t.pass('Successfully caught missing args error');
+ t.fail('Should not have been able to resolve the promise because of missing "txId" parameter');
+ }).catch(function (err) {
+ if (err.message.indexOf('Missing "txId" parameter in the proposal request') >= 0) {
+ t.pass('Successfully caught missing txId error');
} else {
- t.fail('Failed to catch the missing args error. Error: ' + err.stack ? err.stask : err);
+ t.fail('Failed to catch the missing txId error. Error: ' + err.stack ? err.stask : err);
}
+ });
+
+ var p6 = m.queryByChaincode({
+ targets: [hfc.getPeer('grpc://localhost:7051')],
+ chaincodeId: 'blah',
+ chainId: 'blah',
+ fcn: 'init',
+ args: ['a', '100', 'b', '200'],
+ txId: 'blah'
+ }).then(function () {
+ t.fail('Should not have been able to resolve the promise because of missing "nonce" parameter');
}).catch(function (err) {
- if (err.message === 'Missing arguments in Transaction proposal request') {
- t.pass('Successfully caught missing args error');
+ if (err.message.indexOf('Missing "nonce" parameter in the proposal request') >= 0) {
+ t.pass('Successfully caught missing nonce error');
} else {
- t.fail('Failed to catch the missing args error. Error: ' + err.stack ? err.stask : err);
+ t.fail('Failed to catch the missing nonce error. Error: ' + err.stack ? err.stask : err);
}
});
- Promise.all([p1, p2, p3])
+ var p7 = m.queryByChaincode().then(function () {
+ t.fail('Should not have been able to resolve the promise because of missing request parameter');
+ }).catch(function (err) {
+ if (err.message.indexOf('Missing input request object on the proposal request') >= 0) {
+ t.pass('Successfully caught missing request error');
+ } else {
+ t.fail('Failed to catch the missing request error. Error: ' + err.stack ? err.stask : err);
+ }
+ });
+
+ Promise.all([p1, p2, p3, p4, p5, p6, p7])
.then(
function (data) {
t.end();
@@ -768,36 +960,56 @@ test('\n\n ** Member sendTransaction() tests **\n\n', function (t) {
.then(function () {
t.fail('Should not have been able to resolve the promise because of missing parameters');
}, function (err) {
- if (err.message === 'Missing proposalResponse object parameter') {
+ if (err.message.indexOf('Missing input request object on the proposal request') >= 0) {
+ t.pass('Successfully caught missing request error');
+ } else {
+ t.fail('Failed to catch the missing request error. Error: ' + err.stack ? err.stask : err);
+ }
+ });
+
+ var p2 = m.sendTransaction({
+ proposal: 'blah',
+ header: 'blah'
+ })
+ .then(function () {
+ t.fail('Should not have been able to resolve the promise because of missing parameters');
+ }, function (err) {
+ if (err.message.indexOf('Missing "proposalResponse" parameter in transaction request') >= 0) {
t.pass('Successfully caught missing proposalResponse error');
} else {
- t.fail('Failed to catch the missing object error. Error: ' + err.stack ? err.stask : err);
+ t.fail('Failed to catch the missing proposalResponse error. Error: ' + err.stack ? err.stask : err);
}
});
- var p2 = m.sendTransaction('data')
+ var p3 = m.sendTransaction({
+ proposalResponses: 'blah',
+ header: 'blah'
+ })
.then(function () {
t.fail('Should not have been able to resolve the promise because of missing parameters');
}, function (err) {
- if (err.message === 'Missing chaincodeProposal object parameter') {
- t.pass('Successfully caught missing chaincodeProposal error');
+ if (err.message.indexOf('Missing "proposal" parameter in transaction request') >= 0) {
+ t.pass('Successfully caught missing proposal error');
} else {
- t.fail('Failed to catch the missing objet error. Error: ' + err.stack ? err.stask : err);
+ t.fail('Failed to catch the missing proposal error. Error: ' + err.stack ? err.stask : err);
}
});
- var p3 = m.sendTransaction('data', 'data')
+ var p4 = m.sendTransaction({
+ proposalResponses: 'blah',
+ proposal: 'blah'
+ })
.then(function () {
t.fail('Should not have been able to resolve the promise because of missing parameters');
}, function (err) {
- if (err.message === 'no Orderer defined') {
- t.pass('Successfully caught missing orderer error');
+ if (err.message.indexOf('Missing "header" parameter in transaction request') >= 0) {
+ t.pass('Successfully caught missing header error');
} else {
- t.fail('Failed to catch the missing order error. Error: ' + err.stack ? err.stask : err);
+ t.fail('Failed to catch the missing header error. Error: ' + err.stack ? err.stask : err);
}
});
- Promise.all([p1, p2, p3])
+ Promise.all([p1, p2, p3, p4])
.then(
function (data) {
t.end();
@@ -822,6 +1034,13 @@ var TEST_LONG_MSG = 'The Hyperledger project is an open source collaborative eff
'ensure the transparency, longevity, interoperability and support required to bring blockchain technologies forward to mainstream commercial adoption. That ' +
'is what Hyperledger is about – communities of software developers building blockchain frameworks and platforms.';
+var HASH_MSG_SHA3_384 = '9e9c2e5edf6cbc0b512807a8efa2917daff71b83e04dee28fcc00b1a1dd935fb5afc5eafa06bf55bd64792a597e2a8f3';
+var HASH_LONG_MSG_SHA3_384 = '47a90d6721523682e09b81da0a60e6ee1faf839f0503252316638daf038cf682c0a842edaf310eb0f480a2e181a07af0';
+var HASH_MSG_SHA256 = '4e4aa09b6d80efbd684e80f54a70c1d8605625c3380f4cb012b32644a002b5be';
+var HASH_LONG_MSG_SHA256 = '0d98987f5e4e3ea611f0e3d768c594ff9aac25404265d73554d12c86d7f6fbbc';
+var HASH_MSG_SHA3_256 = '7daeff454f7e91e3cd2d1c1bd5fcd1b6c9d4d5fffc6c327710d8fae7b06ee4a3';
+var HASH_LONG_MSG_SHA3_256 = '577174210438a85ae4311a62e5fccf2441b960013f5691993cdf38ed6ba0c84f';
+
var TEST_KEY_PRIVATE = '93f15b31e3c3f3bddcd776d9219e93d8559e31453757b79e193a793cbd239573';
var TEST_KEY_PUBLIC = '04f46815aa00fe2ba2814b906aa4ef1755caf152658de8997a6a858088296054baf45b06b2eba514bcbc37ae0c0cc7465115d36429d0e0bff23dc40e3760c10aa9';
var TEST_MSG_SIGNATURE_SHA2_256 = '3046022100a6460b29373fa16ee96172bfe04666140405fdef78182280545d451f08547736022100d9022fe620ceadabbef1714b894b8d6be4b74c0f9c573bd774871764f4f789c9';
@@ -842,20 +1061,20 @@ test('\n\n ** CryptoSuite_ECDSA_AES - function tests **\n\n', function (t) {
t.equal(true, (typeof cryptoUtils._ecdsaCurve !== 'undefined' && typeof cryptoUtils._ecdsa !== 'undefined'),
'CryptoSuite_ECDSA_AES function tests: default instance has "_ecdsaCurve" and "_ecdsa" properties');
- // test default curve 384 with SHA3_384
- t.equal(cryptoUtils.hash(TEST_MSG), '9e9c2e5edf6cbc0b512807a8efa2917daff71b83e04dee28fcc00b1a1dd935fb5afc5eafa06bf55bd64792a597e2a8f3',
- 'CryptoSuite_ECDSA_AES function tests: using "SHA3" hashing algorithm with default key size which should be 384');
+ // test default curve 256 with SHA256
+ t.equal(cryptoUtils.hash(TEST_MSG), HASH_MSG_SHA256,
+ 'CryptoSuite_ECDSA_AES function tests: using "SHA2" hashing algorithm with default key size which should be 256');
- t.equal(cryptoUtils.hash(TEST_LONG_MSG), '47a90d6721523682e09b81da0a60e6ee1faf839f0503252316638daf038cf682c0a842edaf310eb0f480a2e181a07af0',
- 'CryptoSuite_ECDSA_AES function tests: using "SHA3" hashing algorithm with default key size which should be 384');
+ t.equal(cryptoUtils.hash(TEST_LONG_MSG), HASH_LONG_MSG_SHA256,
+ 'CryptoSuite_ECDSA_AES function tests: using "SHA2" hashing algorithm with default key size which should be 256');
cryptoUtils.generateKey()
.then(function (key) {
- t.equal('secp384r1', key.getPublicKey()._key.curveName,
- 'CryptoSuite_ECDSA_AES constructor tests: cryptoUtils generated public key curveName == secp384r1');
+ t.equal('secp256r1', key.getPublicKey()._key.curveName,
+ 'CryptoSuite_ECDSA_AES constructor tests: cryptoUtils generated public key curveName == secp256r1');
// test curve 256 with SHA3_256
- utils.setConfigSetting('crypto-keysize', 256);
+ utils.setConfigSetting('crypto-hash-algo', 'SHA3');
cryptoUtils = utils.getCryptoSuite();
return cryptoUtils.generateKey();
})
@@ -863,26 +1082,28 @@ test('\n\n ** CryptoSuite_ECDSA_AES - function tests **\n\n', function (t) {
t.equal('secp256r1', key.getPublicKey()._key.curveName,
'CryptoSuite_ECDSA_AES constructor tests: ccryptoUtils generated public key curveName == secp256r1');
- t.equal(cryptoUtils.hash(TEST_MSG), '7daeff454f7e91e3cd2d1c1bd5fcd1b6c9d4d5fffc6c327710d8fae7b06ee4a3',
+ t.equal(cryptoUtils.hash(TEST_MSG), HASH_MSG_SHA3_256,
'CryptoSuite_ECDSA_AES function tests: using "SHA3" hashing algorithm with key size 256');
- t.equal(cryptoUtils.hash(TEST_LONG_MSG), '577174210438a85ae4311a62e5fccf2441b960013f5691993cdf38ed6ba0c84f',
+ t.equal(cryptoUtils.hash(TEST_LONG_MSG), HASH_LONG_MSG_SHA3_256,
'CryptoSuite_ECDSA_AES function tests: using "SHA3" hashing algorithm with key size 256');
- // test SHA2_256
- utils.setConfigSetting('crypto-hash-algo', 'SHA2');
+ // test SHA3_384
+ utils.setConfigSetting('crypto-keysize', 384);
cryptoUtils = utils.getCryptoSuite();
- t.equal(cryptoUtils.hash(TEST_MSG), '4e4aa09b6d80efbd684e80f54a70c1d8605625c3380f4cb012b32644a002b5be',
- 'CryptoSuite_ECDSA_AES function tests: using "SHA2" hashing algorithm with key size 256');
-
- t.equal(cryptoUtils.hash(TEST_LONG_MSG), '0d98987f5e4e3ea611f0e3d768c594ff9aac25404265d73554d12c86d7f6fbbc',
- 'CryptoSuite_ECDSA_AES function tests: using "SHA2" hashing algorithm with key size 256');
+ t.equal(cryptoUtils.hash(TEST_MSG), HASH_MSG_SHA3_384,
+ 'CryptoSuite_ECDSA_AES function tests: using "SHA2" hashing algorithm with key size 384');
+ t.equal(cryptoUtils.hash(TEST_LONG_MSG), HASH_LONG_MSG_SHA3_384,
+ 'CryptoSuite_ECDSA_AES function tests: using "SHA2" hashing algorithm with key size 384');
return cryptoUtils.generateKey();
})
.then(function (key) {
+ t.equal('secp384r1', key.getPublicKey()._key.curveName,
+ 'CryptoSuite_ECDSA_AES constructor tests: ccryptoUtils generated public key curveName == secp384r1');
+
if (!!key._key)
t.pass('CryptoSuite_ECDSA_AES function tests: verify generateKey return object');
else
@@ -890,8 +1111,8 @@ test('\n\n ** CryptoSuite_ECDSA_AES - function tests **\n\n', function (t) {
utils.setConfigSetting('crypto-hash-algo', 'sha3'); //lower or upper case is allowed
cryptoUtils = utils.getCryptoSuite();
- t.equal(cryptoUtils.hash(TEST_MSG), '7daeff454f7e91e3cd2d1c1bd5fcd1b6c9d4d5fffc6c327710d8fae7b06ee4a3',
- 'CryptoSuite_ECDSA_AES function tests: using "SHA3" hashing algorithm with key size 256');
+ t.equal(cryptoUtils.hash(TEST_MSG), HASH_MSG_SHA3_384,
+ 'CryptoSuite_ECDSA_AES function tests: using "SHA3" hashing algorithm with key size 384');
// test generation options
return cryptoUtils.generateKey({ ephemeral: true });
diff --git a/test/unit/util.js b/test/unit/util.js
index 66afc34ea2..4158132b0f 100644
--- a/test/unit/util.js
+++ b/test/unit/util.js
@@ -1,4 +1,6 @@
var path = require('path');
+var copService = require('hfc-cop/lib/FabricCOPImpl.js');
+var Member = require('hfc/lib/Member.js');
module.exports.CHAINCODE_PATH = 'github.com/example_cc';
module.exports.CHAINCODE_MARBLES_PATH = 'github.com/marbles_cc';