Skip to content
This repository was archived by the owner on Apr 22, 2025. It is now read-only.

Commit 2b5907c

Browse files
cdaughtrjimthematrix
authored andcommitted
TxID compute with nonce + creator
Chain.js needs to build the transaction id using nonce and creator to match fabric change 5945. Patch set 1: Only implemented for sendInstallProposal used by end-to-end.js step1. Patch set 2: Implemented all txId's, but could not test. See 'to do' line 1059 - need to get nonce from transaction id? Patch set 3: TxId is working with fix from Angelo. Tested successfully with end-to-end.js step1. Change-Id: Ie9ec9f68a1973269d10fa29fd98578bc0d8d0902 Signed-off-by: cdaughtr <cdaughtr@us.ibm.com>
1 parent 6ceccd0 commit 2b5907c

File tree

4 files changed

+101
-41
lines changed

4 files changed

+101
-41
lines changed

fabric-client/lib/Chain.js

Lines changed: 87 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -871,16 +871,21 @@ var Chain = class {
871871
*/
872872
queryInfo() {
873873
logger.debug('queryInfo - start');
874-
var request = {
875-
targets: [this.getPrimaryPeer()],
876-
chaincodeId : 'qscc',
877-
chainId: '',
878-
txId: utils.buildTransactionID(),
879-
nonce: utils.getNonce(),
880-
fcn : 'GetChainInfo',
881-
args: [ this._name]
882-
};
883-
return this.sendTransactionProposal(request)
874+
var self = this;
875+
var nonce = utils.getNonce();
876+
return this.buildTransactionID_getUserContext(nonce)
877+
.then(function(txId) {
878+
var request = {
879+
targets: [self.getPrimaryPeer()],
880+
chaincodeId : 'qscc',
881+
chainId: '',
882+
txId: txId,
883+
nonce: nonce,
884+
fcn : 'GetChainInfo',
885+
args: [ self._name]
886+
};
887+
return self.sendTransactionProposal(request);
888+
})
884889
.then(
885890
function(results) {
886891
var responses = results[0];
@@ -923,17 +928,22 @@ var Chain = class {
923928
if(!blockHash) {
924929
return Promise.reject( new Error('Blockhash bytes are required'));
925930
}
926-
var request = {
927-
targets: [this.getPrimaryPeer()],
928-
chaincodeId : 'qscc',
929-
chainId: '',
930-
txId: utils.buildTransactionID(),
931-
nonce: utils.getNonce(),
932-
fcn : 'GetBlockByHash',
933-
args: [ this._name],
934-
argbytes : blockHash
935-
};
936-
return this.sendTransactionProposal(request)
931+
var self = this;
932+
var nonce = utils.getNonce();
933+
return this.buildTransactionID_getUserContext(nonce)
934+
.then(function(txId) {
935+
var request = {
936+
targets: [self.getPrimaryPeer()],
937+
chaincodeId : 'qscc',
938+
chainId: '',
939+
txId: txId,
940+
nonce: nonce,
941+
fcn : 'GetBlockByHash',
942+
args: [ self._name],
943+
argbytes : blockHash
944+
};
945+
return self.sendTransactionProposal(request);
946+
})
937947
.then(
938948
function(results) {
939949
var responses = results[0];
@@ -980,16 +990,21 @@ var Chain = class {
980990
} else {
981991
return Promise.reject( new Error('Block number must be a postive integer'));
982992
}
983-
var request = {
984-
targets: [this.getPrimaryPeer()],
985-
chaincodeId : 'qscc',
986-
chainId: '',
987-
txId: utils.buildTransactionID(),
988-
nonce: utils.getNonce(),
989-
fcn : 'GetBlockByNumber',
990-
args: [ this._name, block_number]
991-
};
992-
return this.sendTransactionProposal(request)
993+
var self = this;
994+
var nonce = utils.getNonce();
995+
return this.buildTransactionID_getUserContext(nonce)
996+
.then(function(txId) {
997+
var request = {
998+
targets: [self.getPrimaryPeer()],
999+
chaincodeId : 'qscc',
1000+
chainId: '',
1001+
txId: txId,
1002+
nonce: nonce,
1003+
fcn : 'GetBlockByNumber',
1004+
args: [ self._name, block_number]
1005+
};
1006+
return self.sendTransactionProposal(request);
1007+
})
9931008
.then(
9941009
function(results) {
9951010
var responses = results[0];
@@ -1040,8 +1055,8 @@ var Chain = class {
10401055
targets: [this.getPrimaryPeer()],
10411056
chaincodeId : 'qscc',
10421057
chainId: '',
1043-
txId: utils.buildTransactionID(),
1044-
nonce: utils.getNonce(),
1058+
txId: transactionID,
1059+
nonce: utils.getNonce(),//to do - get nonce from transaction id
10451060
fcn : 'GetTransactionByID',
10461061
args: [ this._name, transaction_id]
10471062
};
@@ -1190,10 +1205,11 @@ var Chain = class {
11901205
return self._clientContext.getUserContext()
11911206
.then(
11921207
function(userContext) {
1208+
var txId = self.buildTransactionID(request.nonce, userContext);
11931209
var channelHeader = buildChannelHeader(
11941210
_commonProto.HeaderType.ENDORSER_TRANSACTION,
11951211
'', //install does not target a channel
1196-
request.txId,
1212+
txId,
11971213
null,
11981214
'lccc'
11991215
);
@@ -1708,6 +1724,43 @@ var Chain = class {
17081724
return errorMsg;
17091725
}
17101726

1727+
/**
1728+
* Utility method to build an unique transaction id
1729+
* based on a nonce and this chain's user.
1730+
* @param {int} nonce - a one time use number
1731+
* @param {User} userContext - the user context
1732+
* @returns {string} An unique string
1733+
*/
1734+
buildTransactionID(nonce, userContext) {
1735+
logger.debug('buildTransactionID - start');
1736+
var creator_bytes = userContext.getIdentity().serialize();//same as signatureHeader.Creator
1737+
var nonce_bytes = nonce;//nonce is already in bytes
1738+
var trans_bytes = Buffer.concat([nonce_bytes, creator_bytes]);
1739+
var trans_hash = this.cryptoPrimitives.hash(trans_bytes);
1740+
var transaction_id = Buffer.from(trans_hash).toString();
1741+
logger.debug('buildTransactionID - transaction_id %s',transaction_id);
1742+
return transaction_id;
1743+
}
1744+
1745+
/**
1746+
* Utility method to build an unique transaction id
1747+
* based on a nonce and this chain's user.
1748+
* Gets the user context.
1749+
* @param {int} nonce - a one time use number
1750+
* @returns {Promise} A promise for the transaction id
1751+
*/
1752+
buildTransactionID_getUserContext(nonce) {
1753+
return this._clientContext.getUserContext()
1754+
.then((userContext) => {
1755+
logger.debug('buildTransactionID_getUserContext - got userContext');
1756+
return this.buildTransactionID(nonce, userContext);
1757+
})
1758+
.catch(function(error) {
1759+
logger.debug('buildTransactionID_getUserContext - caught error ::' + error.stack ? error.stack : error);
1760+
return Promise.reject(new Error(error));
1761+
});
1762+
}
1763+
17111764
/**
17121765
* return a printable representation of this object
17131766
*/

test/integration/chain-fabriccop-tests.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ var utils = require('fabric-client/lib/utils.js');
2525
var User = require('fabric-client/lib/User.js');
2626
var Client = require('fabric-client/lib/Client.js');
2727

28-
var testUtil = require('./util.js');
28+
var testUtil = require('../unit/util.js');
2929

3030
var keyValStorePath = testUtil.KVS;
3131

test/integration/end-to-end.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ test('End-to-end flow of chaincode install, deploy, transaction invocation, and
145145
t.end();
146146
}).then((nothing) => {
147147
t.pass('Successfully waited on timer');
148+
if (useSteps) t.end();
148149
},
149150
(err) => {
150151
t.fail('Failed to wait on timer: ' + err.stack ? err.stack : err);
@@ -332,7 +333,7 @@ test('End-to-end flow of chaincode install, deploy, transaction invocation, and
332333
t.fail('Failed to send transaction proposal due to error: ' + err.stack ? err.stack : err);
333334
t.end();
334335
}).then((response) => {
335-
if (response.status === 'SUCCESS') {
336+
if (response && response.status === 'SUCCESS') {
336337
t.pass('Successfully ordered endorsement transaction.');
337338
} else {
338339
t.fail('Failed to order the endorsement of the transaction. Error code: ' + response.status);
@@ -363,13 +364,19 @@ test('End-to-end flow of chaincode install, deploy, transaction invocation, and
363364
return chain.queryByChaincode(request);
364365
},
365366
(err) => {
366-
t.fail('Failed to get transaction notification within the timeout period');
367+
t.comment('Failed to get transaction notification within the timeout period. exiting...');
368+
t.fail('Error: ' + err.stack ? err.stack : err );
367369
t.end();
368370
}).then((response_payloads) => {
369-
for(let i = 0; i < response_payloads.length; i++) {
370-
t.equal(response_payloads[i].toString('utf8'),'300','checking query results are correct that user b has 300 now after the move');
371+
if (response_payloads) {
372+
for(let i = 0; i < response_payloads.length; i++) {
373+
t.equal(response_payloads[i].toString('utf8'),'300','checking query results are correct that user b has 300 now after the move');
374+
}
375+
t.end();
376+
} else {
377+
t.fail('response_payloads is null');
378+
t.end();
371379
}
372-
t.end();
373380
},
374381
(err) => {
375382
t.fail('Failed to send query due to error: ' + err.stack ? err.stack : err);
@@ -380,6 +387,7 @@ test('End-to-end flow of chaincode install, deploy, transaction invocation, and
380387
});
381388
}
382389
});
390+
t.end();
383391
});
384392

385393
function sleep(ms) {

test/unit/chain.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,6 @@ test('\n\n ** Chain sendInstallProposal() tests **\n\n', function (t) {
544544
chaincodePath: 'blah',
545545
chaincodeId: 'blah',
546546
chaincodeVersion: 'blah',
547-
chainId: 'blah',
548547
txId: 'blah',
549548
nonce: 'blah'
550549
}).then(function () {

0 commit comments

Comments
 (0)