Skip to content
This repository has been archived by the owner on Mar 8, 2020. It is now read-only.

Commit

Permalink
correct handling of tx id (#3847)
Browse files Browse the repository at this point in the history
* correct handling of tx id

Signed-off-by: Matthew B White <[email protected]>

* additional to bnc from review comments

Signed-off-by: Matthew B White <[email protected]>

* update test code and coverage

Signed-off-by: Matthew B White <[email protected]>

* update the rest and loglevel tests

Signed-off-by: Matthew B White <[email protected]>

* mend

Signed-off-by: Matthew B White <[email protected]>

* additional package.json that needed cleaning

Signed-off-by: Matthew B White <[email protected]>
  • Loading branch information
mbwhite authored and Dave Kelsey committed May 9, 2018
1 parent 82ad8b2 commit 0a1d885
Show file tree
Hide file tree
Showing 15 changed files with 193 additions and 109 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,4 @@
}
}
}
}
}
16 changes: 10 additions & 6 deletions packages/composer-admin/lib/adminconnection.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ const Factory = require('composer-common').Factory;
const Logger = require('composer-common').Logger;
const ModelManager = require('composer-common').ModelManager;
const Util = require('composer-common').Util;
const uuid = require('uuid');
const IdCard = require('composer-common').IdCard;
const Serializer = require('composer-common').Serializer;

Expand Down Expand Up @@ -287,11 +286,12 @@ class AdminConnection {
// Get the current identity - we may need it to bind the
// identity to a network admin participant.
return Promise.resolve()
.then(() => {
.then(()=>{

// Create a new instance of a start transaction.
const startTransaction = systemFactory.newTransaction('org.hyperledger.composer.system', 'StartBusinessNetwork');
const startTransaction = systemFactory.newTransaction('org.hyperledger.composer.system', 'StartBusinessNetwork',startOptions.transactionId.idStr);
const classDeclaration = startTransaction.getClassDeclaration();
delete startOptions.transactionId;

let hasNetworkAdmins = startOptions && startOptions.networkAdmins && startOptions.networkAdmins.length > 0;
let hasBootStrapTransactions = startOptions && startOptions.bootstrapTransactions && startOptions.bootstrapTransactions.length > 0;
Expand Down Expand Up @@ -444,7 +444,11 @@ class AdminConnection {
Util.securityCheck(this.securityContext);
let networkAdmins = startOptions.networkAdmins;
// Build the start transaction.
return this._buildStartTransaction(startOptions)
return Util.createTransactionId(this.securityContext)
.then((id) =>{
startOptions.transactionId = id;
return this._buildStartTransaction(startOptions);
})
.then((startTransactionJSON) => {
// Now we can start the business network.
return this.connection.start(this.securityContext, networkName, networkVersion, JSON.stringify(startTransactionJSON), startOptions);
Expand Down Expand Up @@ -619,13 +623,13 @@ class AdminConnection {
LOG.entry(method);
const json = {
$class : 'org.hyperledger.composer.system.ActivateCurrentIdentity',
transactionId : uuid.v4(),
timestamp : new Date().toISOString()
};
return Util.invokeChainCode(this.securityContext, 'submitTransaction', [JSON.stringify(json)])
return Util.submitTransaction(this.securityContext,json)
.then(() => {
LOG.exit(method);
});

}

/**
Expand Down
22 changes: 12 additions & 10 deletions packages/composer-admin/test/adminconnection.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const IdCard = require('composer-common').IdCard;
const NetworkCardStoreManager = require('composer-common').NetworkCardStoreManager;
const SecurityContext = require('composer-common').SecurityContext;
const Util = require('composer-common').Util;
const uuid = require('uuid');


const version = require('../package.json').version;

Expand All @@ -40,7 +40,7 @@ describe('AdminConnection', () => {
name: testProfileName,
'x-type': 'hlfv1'
};

const startTxId = {idStr:'c89291eb-969f-4b04-b653-82deb5ee0ba1'};
let mockConnectionManager;
let mockConnection;
let mockSecurityContext;
Expand Down Expand Up @@ -107,7 +107,7 @@ describe('AdminConnection', () => {
faultyCard = new IdCard(faultyMetaData, minimalConnectionProfile);
credentialsCard = new IdCard(minimalMetadata, minimalConnectionProfile);
credentialsCard.setCredentials(validCredentials);

sandbox.stub(Util, 'createTransactionId').resolves(startTxId);
});

afterEach(() => {
Expand Down Expand Up @@ -236,6 +236,7 @@ describe('AdminConnection', () => {
});

describe('#start', () => {

const networkName = 'network-name';
const networkVersion = '1.0.0-test';
const identityName = 'admin';
Expand Down Expand Up @@ -268,7 +269,7 @@ describe('AdminConnection', () => {
const expectedStartTransaction = {
$class : 'org.hyperledger.composer.system.StartBusinessNetwork',
timestamp : '1970-01-01T00:00:00.000Z',
transactionId : sinon.match.string
transactionId : startTxId.idStr
};
const expectedNetworkAdminBootstrapTransactions = {
bootstrapTransactions : [
Expand Down Expand Up @@ -317,6 +318,7 @@ describe('AdminConnection', () => {
mockSecurityContext.getUser.returns(identityName);
adminConnection.connection = mockConnection;
adminConnection.securityContext = mockSecurityContext;

});

it('should error if neither networkAdmins or bootstrapTransactions specified', () => {
Expand Down Expand Up @@ -494,14 +496,14 @@ describe('AdminConnection', () => {
mockConnection.ping.onSecondCall().resolves(Buffer.from(JSON.stringify({
version : version
})));
sandbox.stub(uuid, 'v4').returns('c89291eb-969f-4b04-b653-82deb5ee0ba1');

mockConnection.invokeChainCode.resolves();
adminConnection.connection = mockConnection;
return adminConnection.ping()
.then(() => {
sinon.assert.calledTwice(mockConnection.ping);
sinon.assert.calledOnce(mockConnection.invokeChainCode);
sinon.assert.calledWith(mockConnection.invokeChainCode, mockSecurityContext, 'submitTransaction', ['{"$class":"org.hyperledger.composer.system.ActivateCurrentIdentity","transactionId":"c89291eb-969f-4b04-b653-82deb5ee0ba1","timestamp":"1970-01-01T00:00:00.000Z"}']);
sinon.assert.calledWith(mockConnection.invokeChainCode, mockSecurityContext, 'submitTransaction', ['{"$class":"org.hyperledger.composer.system.ActivateCurrentIdentity","timestamp":"1970-01-01T00:00:00.000Z","transactionId":"c89291eb-969f-4b04-b653-82deb5ee0ba1"}']);
});
});

Expand Down Expand Up @@ -538,23 +540,23 @@ describe('AdminConnection', () => {

it('should perform a security check', () => {
sandbox.stub(Util, 'securityCheck');
sandbox.stub(uuid, 'v4').returns('c89291eb-969f-4b04-b653-82deb5ee0ba1');

mockConnection.invokeChainCode.resolves();
adminConnection.connection = mockConnection;
return adminConnection.activate()
.then(() => {
sinon.assert.calledOnce(Util.securityCheck);
sinon.assert.calledTwice(Util.securityCheck);
});
});

it('should submit a request to the chaincode for activation', () => {
sandbox.stub(uuid, 'v4').returns('c89291eb-969f-4b04-b653-82deb5ee0ba1');

mockConnection.invokeChainCode.resolves();
adminConnection.connection = mockConnection;
return adminConnection.activate()
.then(() => {
sinon.assert.calledOnce(mockConnection.invokeChainCode);
sinon.assert.calledWith(mockConnection.invokeChainCode, mockSecurityContext, 'submitTransaction', ['{"$class":"org.hyperledger.composer.system.ActivateCurrentIdentity","transactionId":"c89291eb-969f-4b04-b653-82deb5ee0ba1","timestamp":"1970-01-01T00:00:00.000Z"}']);
sinon.assert.calledWith(mockConnection.invokeChainCode, mockSecurityContext, 'submitTransaction', ['{"$class":"org.hyperledger.composer.system.ActivateCurrentIdentity","timestamp":"1970-01-01T00:00:00.000Z","transactionId":"c89291eb-969f-4b04-b653-82deb5ee0ba1"}']);
});
});

Expand Down
14 changes: 3 additions & 11 deletions packages/composer-client/lib/businessnetworkconnection.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ const Resource = require('composer-common').Resource;
const TransactionDeclaration = require('composer-common').TransactionDeclaration;
const TransactionRegistry = require('./transactionregistry');
const Util = require('composer-common').Util;
const uuid = require('uuid');
const Registry = require('./registry');
const NetworkCardStoreManager = require('composer-common').NetworkCardStoreManager;
const LOG = Logger.getLog('BusinessNetworkConnection');
Expand Down Expand Up @@ -519,15 +518,9 @@ class BusinessNetworkConnection extends EventEmitter {
if (!(classDeclaration instanceof TransactionDeclaration)) {
throw new Error(classDeclaration.getFullyQualifiedName() + ' is not a transaction');
}
transaction.timestamp = new Date();

return Util.createTransactionId(this.securityContext)
.then((id) => {
transaction.setIdentifier(id.idStr);
transaction.timestamp = new Date();
let data = this.getBusinessNetwork().getSerializer().toJSON(transaction);
return Util.invokeChainCode(this.securityContext, 'submitTransaction', [JSON.stringify(data)], { transactionId: id.id });
});

return Util.submitTransaction(this.securityContext,transaction,this.getBusinessNetwork().getSerializer());
}

/**
Expand Down Expand Up @@ -665,10 +658,9 @@ class BusinessNetworkConnection extends EventEmitter {
LOG.entry(method);
const json = {
$class: 'org.hyperledger.composer.system.ActivateCurrentIdentity',
transactionId: uuid.v4(),
timestamp: new Date().toISOString()
};
return Util.invokeChainCode(this.securityContext, 'submitTransaction', [JSON.stringify(json)])
return Util.submitTransaction(this.securityContext, json)
.then(() => {
LOG.exit(method);
});
Expand Down
23 changes: 15 additions & 8 deletions packages/composer-client/test/businessnetworkconnection.js
Original file line number Diff line number Diff line change
Expand Up @@ -815,9 +815,6 @@ describe('BusinessNetworkConnection', () => {
const tx = factory.newTransaction('org.acme.sample', 'SampleTransaction');
delete tx.$identifier;

// Stub the UUID generator.
sandbox.stub(uuid, 'v4').returns('c89291eb-969f-4b04-b653-82deb5ee0ba1');

// Set up the responses from the chain-code.
sandbox.stub(Util, 'invokeChainCode').resolves();
sandbox.stub(Util, 'createTransactionId').resolves({
Expand Down Expand Up @@ -1044,14 +1041,17 @@ describe('BusinessNetworkConnection', () => {
mockConnection.ping.onSecondCall().resolves(Buffer.from(JSON.stringify({
version : version
})));
sandbox.stub(uuid, 'v4').returns('c89291eb-969f-4b04-b653-82deb5ee0ba1');
sandbox.stub(Util, 'createTransactionId').resolves({
id : 'c89291eb-969f-4b04-b653-82deb5ee0ba1',
idStr : 'c89291eb-969f-4b04-b653-82deb5ee0ba1'
});
mockConnection.invokeChainCode.resolves();
businessNetworkConnection.connection = mockConnection;
return businessNetworkConnection.ping()
.then(() => {
sinon.assert.calledTwice(mockConnection.ping);
sinon.assert.calledOnce(mockConnection.invokeChainCode);
sinon.assert.calledWith(mockConnection.invokeChainCode, mockSecurityContext, 'submitTransaction', ['{"$class":"org.hyperledger.composer.system.ActivateCurrentIdentity","transactionId":"c89291eb-969f-4b04-b653-82deb5ee0ba1","timestamp":"1970-01-01T00:00:00.000Z"}']);
sinon.assert.calledWith(mockConnection.invokeChainCode, mockSecurityContext, 'submitTransaction', ['{"$class":"org.hyperledger.composer.system.ActivateCurrentIdentity","timestamp":"1970-01-01T00:00:00.000Z","transactionId":"c89291eb-969f-4b04-b653-82deb5ee0ba1"}']);
});
});

Expand Down Expand Up @@ -1089,21 +1089,28 @@ describe('BusinessNetworkConnection', () => {
it('should perform a security check', () => {
sandbox.stub(Util, 'securityCheck');
mockConnection.invokeChainCode.resolves();
sandbox.stub(Util, 'createTransactionId').resolves({
id : 'c89291eb-969f-4b04-b653-82deb5ee0ba1',
idStr : 'c89291eb-969f-4b04-b653-82deb5ee0ba1'
});
businessNetworkConnection.connection = mockConnection;
return businessNetworkConnection.activate()
.then(() => {
sinon.assert.calledOnce(Util.securityCheck);
sinon.assert.calledTwice(Util.securityCheck);
});
});

it('should submit a request to the chaincode for activation', () => {
sandbox.stub(uuid, 'v4').returns('c89291eb-969f-4b04-b653-82deb5ee0ba1');
sandbox.stub(Util, 'createTransactionId').resolves({
id : 'c89291eb-969f-4b04-b653-82deb5ee0ba1',
idStr : 'c89291eb-969f-4b04-b653-82deb5ee0ba1'
});
mockConnection.invokeChainCode.resolves();
businessNetworkConnection.connection = mockConnection;
return businessNetworkConnection.activate()
.then(() => {
sinon.assert.calledOnce(mockConnection.invokeChainCode);
sinon.assert.calledWith(mockConnection.invokeChainCode, mockSecurityContext, 'submitTransaction', ['{"$class":"org.hyperledger.composer.system.ActivateCurrentIdentity","transactionId":"c89291eb-969f-4b04-b653-82deb5ee0ba1","timestamp":"1970-01-01T00:00:00.000Z"}']);
sinon.assert.calledWith(mockConnection.invokeChainCode, mockSecurityContext, 'submitTransaction', ['{"$class":"org.hyperledger.composer.system.ActivateCurrentIdentity","timestamp":"1970-01-01T00:00:00.000Z","transactionId":"c89291eb-969f-4b04-b653-82deb5ee0ba1"}']);
});
});

Expand Down
25 changes: 2 additions & 23 deletions packages/composer-common/lib/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ const BusinessNetworkDefinition = require('./businessnetworkdefinition.js');
const ConnectionManager = require('./connectionmanager');
const EventEmitter = require('events');
const Util = require('./util');
const uuid = require('uuid');

/**
* Base class representing a connection to a business network.
Expand Down Expand Up @@ -167,17 +166,7 @@ class Connection extends EventEmitter {
}

let transaction = currentDeployedNetwork.getFactory().newTransaction('org.hyperledger.composer.system','ResetBusinessNetwork');
let id = transaction.getIdentifier();
if (id === null || id === undefined) {
id = uuid.v4();
transaction.setIdentifier(id);
}
let timestamp = transaction.timestamp;
if (timestamp === null || timestamp === undefined) {
timestamp = transaction.timestamp = new Date();
}
let data = currentDeployedNetwork.getSerializer().toJSON(transaction);
await Util.invokeChainCode(securityContext, 'submitTransaction', [JSON.stringify(data)]);
return Util.submitTransaction(securityContext,transaction,currentDeployedNetwork.getSerializer());
}

/**
Expand All @@ -200,18 +189,8 @@ class Connection extends EventEmitter {
let currentDeployedNetwork = await BusinessNetworkDefinition.fromArchive(businessNetworkArchive);

let transaction = currentDeployedNetwork.getFactory().newTransaction('org.hyperledger.composer.system','SetLogLevel');
let id = transaction.getIdentifier();
if (id === null || id === undefined) {
id = uuid.v4();
transaction.setIdentifier(id);
}
let timestamp = transaction.timestamp;
if (timestamp === null || timestamp === undefined) {
timestamp = transaction.timestamp = new Date();
}
transaction.newLogLevel = loglevel;
let data = currentDeployedNetwork.getSerializer().toJSON(transaction);
await Util.invokeChainCode(securityContext, 'submitTransaction', [JSON.stringify(data)]);
return Util.submitTransaction(securityContext,transaction,currentDeployedNetwork.getSerializer());
}

/**
Expand Down
30 changes: 29 additions & 1 deletion packages/composer-common/lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
*/

'use strict';

const Resource = require('./model/resource');
const Globalize = require('./globalize');
const os = require('os');
const path = require('path');
Expand Down Expand Up @@ -96,6 +96,34 @@ class Util {
return securityContext.getConnection().invokeChainCode(securityContext, functionName, args, options);
}

/**
* Takes a json structure of a transaction, and processes this for transaction id
* Passes it on to the invokeChainCode fn
*
* @param {SecurityContext} securityContext - The user's security context
* @param {resource|object} transaction - the transaction
* @param {Serializer} [serializer] needed ONLY if the transaction passed is not a resource but pure json
* @param {string} [functionName] The name of the function to call default is submitTransaction.
*/
static async submitTransaction(securityContext, transaction, serializer,functionName = 'submitTransaction'){
Util.securityCheck(securityContext);

let txId = await Util.createTransactionId(securityContext);
let json;

if (transaction instanceof Resource){
transaction.setIdentifier(txId.idStr);
json = serializer.toJSON(transaction);

} else {
transaction.transactionId = txId.idStr;
json=transaction;
}

await Util.invokeChainCode(securityContext, functionName, [JSON.stringify(json)], { transactionId: txId.id });

}

/**
* Returns true if the typeof the object === 'undefined' or
* the object === null.
Expand Down
3 changes: 2 additions & 1 deletion packages/composer-common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@
".yml",
".yaml",
".txt",
".zip"
".zip",
".tgz"
],
"insert_license": false,
"license_formats": {
Expand Down
Loading

0 comments on commit 0a1d885

Please sign in to comment.