Skip to content

Commit

Permalink
[FAB-16101] Handle chaincode invoke without args
Browse files Browse the repository at this point in the history
Change-Id: I70ee42997674dcc1edeb93cde6991e28c77eb87d
Signed-off-by: James Taylor <jamest@uk.ibm.com>
  • Loading branch information
jt-nti committed Oct 16, 2019
1 parent f7e5b57 commit d90bdfd
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 26 deletions.
30 changes: 15 additions & 15 deletions libraries/fabric-shim/lib/contract-spi/chaincodefromcontract.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,8 @@ class ChaincodeFromContract {
return errors;
}

/** Load the contract implementation code
*
/**
* Load the contract implementation code
*/
_resolveContractImplementations(contractClasses) {
logger.debug('Supplied contract classes', contractClasses);
Expand Down Expand Up @@ -303,14 +303,7 @@ class ChaincodeFromContract {
* @param {ChaincodeStub} stub Stub class giving the full api
*/
async Init(stub) {
const args = stub.getBufferArgs();
if (args.length >= 1) {
const fnName = args[0].toString();
return this.invokeFunctionality(stub, fnName, args.slice(1));
} else {
const message = 'Default initiator successful.';
return shim.success(Buffer.from(message));
}
return this.invokeFunctionality(stub);
}

/**
Expand All @@ -319,9 +312,7 @@ class ChaincodeFromContract {
* @param {ChaincodeStub} stub Stub class giving the full api
*/
async Invoke(stub) {
const args = stub.getBufferArgs();
const fnName = args[0].toString();
return this.invokeFunctionality(stub, fnName, args.slice(1));
return this.invokeFunctionality(stub);
}

/**
Expand All @@ -330,7 +321,16 @@ class ChaincodeFromContract {
* @param {ChaincodeStub} stub Stub class giving the full api
* @param {Object} fAndP Function and Paramters obtained from the smart contract argument
*/
async invokeFunctionality(stub, fAndP, bufferArgs) {
async invokeFunctionality(stub) {
const bufferArgs = stub.getBufferArgs();
if ((!bufferArgs) || (bufferArgs.length < 1)) {
const message = 'Default initiator successful.';
return shim.success(Buffer.from(message));
}

const fAndP = bufferArgs[0].toString();
const txArgs = bufferArgs.slice(1);

const txID = stub.getTxID();
const channelID = stub.getChannelID();
const loggerPrefix = utils.generateLoggingPrefix(channelID, txID);
Expand Down Expand Up @@ -369,7 +369,7 @@ class ChaincodeFromContract {

// marhsall the parameters into the correct types for hanlding by
// the tx function
const parameters = dataMarshall.handleParameters(functionExists, bufferArgs, loggerPrefix);
const parameters = dataMarshall.handleParameters(functionExists, txArgs, loggerPrefix);

// before tx
await contractInstance.beforeTransaction(ctx);
Expand Down
2 changes: 1 addition & 1 deletion libraries/fabric-shim/test/unit/chaincode.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe('Chaincode', () => {
Chaincode.Init();
});

it ('should be able to call the init method', () => {
it ('should be able to call the invoke method', () => {
Chaincode = new (require(chaincodePath).ChaincodeInterface)();
Chaincode.Invoke();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,14 @@ describe('chaincodefromcontract', () => {
sandbox.replace(shim, 'success', fakeSuccess);
sandbox.replace(shim, 'error', fakeError);
});

it('should handle no args', function() {
const cc = new ChaincodeFromContract([SCAlpha], defaultSerialization);

const mockStub = {getBufferArgs: sandbox.stub().returns()};
return cc.Init(mockStub).should.eventually.be.fulfilled;
});

it('should handle a single class being passed as a contract', () => {
const systemContract = new SystemContract();
sandbox.stub(ChaincodeFromContract.prototype, '_resolveContractImplementations')
Expand Down Expand Up @@ -435,6 +443,14 @@ describe('chaincodefromcontract', () => {
});

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

it('should handle no args', function() {
const cc = new ChaincodeFromContract([SCAlpha], defaultSerialization);

const mockStub = {getBufferArgs: sandbox.stub().returns()};
return cc.Invoke(mockStub).should.eventually.be.fulfilled;
});

it('should handle a single class being passed as a contract', () => {
const systemContract = new SystemContract();
sandbox.stub(ChaincodeFromContract.prototype, '_resolveContractImplementations')
Expand Down Expand Up @@ -606,15 +622,15 @@ describe('chaincodefromcontract', () => {


const mockStub = {
getBufferArgs: sandbox.stub().returns([]),
getBufferArgs: sandbox.stub().returns(['name:missing', Buffer.from('args2')]),
getTxID: () => {
return 'a tx id';
},
getChannelID: () => {
return 'a channel id';
}
};
await cc.invokeFunctionality(mockStub, 'name:missing', [Buffer.from('args2')]);
await cc.invokeFunctionality(mockStub);

sinon.assert.called(fakeError);
sinon.assert.notCalled(fakeSuccess);
Expand Down Expand Up @@ -663,7 +679,7 @@ describe('chaincodefromcontract', () => {
};

const mockStub = {
getBufferArgs: sandbox.stub().returns([]),
getBufferArgs: sandbox.stub().returns(['name:fn', Buffer.from('args2')]),
getCreator: sandbox.stub().returns(mockSigningId),
getTxID: () => {
return 'a tx id';
Expand All @@ -674,7 +690,7 @@ describe('chaincodefromcontract', () => {
};
cc.contractImplementations.name = nameMetadata;

await cc.invokeFunctionality(mockStub, 'name:fn', [Buffer.from('args2')]);
await cc.invokeFunctionality(mockStub);
sinon.assert.called(fakeSuccess);
sinon.assert.notCalled(fakeError);

Expand Down Expand Up @@ -709,7 +725,7 @@ describe('chaincodefromcontract', () => {
};

const mockStub = {
getBufferArgs: sandbox.stub().returns([]),
getBufferArgs: sandbox.stub().returns(['name:fn', Buffer.from('args2')]),
getCreator: sandbox.stub().returns(mockSigningId),
getTxID: () => {
return 'a tx id';
Expand All @@ -733,7 +749,7 @@ describe('chaincodefromcontract', () => {
}
};

await cc.invokeFunctionality(mockStub, 'name:fn', [Buffer.from('args2')]);
await cc.invokeFunctionality(mockStub);
sinon.assert.called(fakeError);
sinon.assert.notCalled(fakeSuccess);

Expand Down Expand Up @@ -769,7 +785,7 @@ describe('chaincodefromcontract', () => {
};

const mockStub = {
getBufferArgs: sandbox.stub().returns([]),
getBufferArgs: sandbox.stub().returns(['name:fn', Buffer.from('args2')]),
getCreator: sandbox.stub().returns(mockSigningId),
getTxID: () => {
return 'a tx id';
Expand Down Expand Up @@ -802,7 +818,7 @@ describe('chaincodefromcontract', () => {
}
};

await cc.invokeFunctionality(mockStub, 'name:fn', [Buffer.from('args2')]);
await cc.invokeFunctionality(mockStub);
sinon.assert.calledWith(cc.contractImplementations.name.dataMarshall.handleParameters, {name: 'fn'}, [Buffer.from('args2')], 'a logging prefix');
sinon.assert.calledWith(cc.contractImplementations.name.dataMarshall.toWireBuffer, 'hello world', undefined, 'a logging prefix');
sinon.assert.called(fakeSuccess);
Expand Down Expand Up @@ -837,7 +853,7 @@ describe('chaincodefromcontract', () => {
};

const mockStub = {
getBufferArgs: sandbox.stub().returns([]),
getBufferArgs: sandbox.stub().returns(['name:fn', Buffer.from('args2')]),
getCreator: sandbox.stub().returns(mockSigningId),
getTxID: () => {
return 'a tx id';
Expand Down Expand Up @@ -874,7 +890,7 @@ describe('chaincodefromcontract', () => {
}
};

await cc.invokeFunctionality(mockStub, 'name:fn', [Buffer.from('args2')]);
await cc.invokeFunctionality(mockStub);
sinon.assert.calledWith(cc.contractImplementations.name.dataMarshall.handleParameters, cc.contractImplementations.name.transactions[0], [Buffer.from('args2')], 'a logging prefix');
sinon.assert.calledWith(cc.contractImplementations.name.dataMarshall.toWireBuffer, 'hello world', {type: 'string'}, 'a logging prefix');
sinon.assert.called(fakeSuccess);
Expand Down

0 comments on commit d90bdfd

Please sign in to comment.