Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions libraries/fabric-shim/lib/handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -375,11 +375,35 @@ class ChaincodeMessageHandler {
}

async handleGetMultipleStates(keys, channel_id, txid) {
return await Promise.all(keys.map(key => this.handleGetState('', key, channel_id, txid)));
const msgPb = new peer.GetStateMultiple();
msgPb.setCollection('');
msgPb.setKeysList(keys);
const msg = mapToChaincodeMessage({
type: peer.ChaincodeMessage.Type.GET_STATE_MULTIPLE,
payload: msgPb.serializeBinary(),
txid: txid,
channel_id: channel_id
});
logger.debug('handleGetMultipleStates - with keys:', keys);
const response = await this._askPeerAndListen(msg, 'GET_STATE_MULTIPLE');
const decodedResponse = peer.GetStateMultipleResult.deserializeBinary(response.payload);
return decodedResponse.getValuesList();
}

async handleGetMultiplePrivateData(collection, keys, channel_id, txid) {
return await Promise.all(keys.map(key => this.handleGetState(collection, key, channel_id, txid)));
const msgPb = new peer.GetStateMultiple();
msgPb.setCollection(collection);
msgPb.setKeysList(keys);
const msg = mapToChaincodeMessage({
type: peer.ChaincodeMessage.Type.GET_STATE_MULTIPLE,
payload: msgPb.serializeBinary(),
txid: txid,
channel_id: channel_id
});
logger.debug('handleGetMultiplePrivateData - with collection:', collection, 'keys:', keys);
const response = await this._askPeerAndListen(msg, 'GET_STATE_MULTIPLE');
const decodedResponse = peer.GetStateMultipleResult.deserializeBinary(response.payload);
return decodedResponse.getValuesList();
}

async handleGetState(collection, key, channel_id, txId) {
Expand Down
16 changes: 8 additions & 8 deletions libraries/fabric-shim/test/typescript/chaincode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,14 @@ class TestTS implements ChaincodeInterface {
this.testStateQueryIterator(queryResult);
}

async testIterator(iterator: Iterators.CommonIterator<any>) {
const historyNext: Promise<any> = iterator.next();
const nextVal: any = await historyNext;
async testIterator(iterator: Iterators.CommonIterator<unknown>): Promise<void> {
const historyNext: Promise<unknown> = iterator.next();
const nextVal: unknown = await historyNext;
const historyClose: Promise<void> = iterator.close();
await historyClose;
}

async testHistoryQueryIterator(historyQuery: Iterators.HistoryQueryIterator) {
async testHistoryQueryIterator(historyQuery: Iterators.HistoryQueryIterator): Promise<void> {
const historyNext: Iterators.NextKeyModificationResult = await historyQuery.next();
await historyQuery.close();
const done: boolean = historyNext.done;
Expand All @@ -165,7 +165,7 @@ class TestTS implements ChaincodeInterface {
const value: Uint8Array = keyMod.value;
}

async testStateQueryIterator(stateQuery: Iterators.StateQueryIterator) {
async testStateQueryIterator(stateQuery: Iterators.StateQueryIterator): Promise<void> {
const stateNext: Iterators.NextResult<Iterators.KV> = await stateQuery.next();
await stateQuery.close();
const done: boolean = stateNext.done;
Expand Down Expand Up @@ -238,7 +238,7 @@ class TestTS implements ChaincodeInterface {
this.testSignedProposal(proposal);
}

testSignedProposal(proposal: ChaincodeProposal.SignedProposal) {
testSignedProposal(proposal: ChaincodeProposal.SignedProposal): void {
const prop: ChaincodeProposal.Proposal = proposal.proposal;
const sig: Uint8Array = proposal.signature;

Expand All @@ -263,12 +263,12 @@ class TestTS implements ChaincodeInterface {
const map: Map<string, Uint8Array> = payload.transientMap;
}

testQueryResponseMetadata(metadata: QueryResponseMetadata) {
testQueryResponseMetadata(metadata: QueryResponseMetadata): void {
const cnt: number = metadata.fetchedRecordsCount;
const bookmark: string = metadata.bookmark;
}

async testStateBasedEP(stub: ChaincodeStub) {
async testStateBasedEP(stub: ChaincodeStub): Promise<void> {
const ep = new KeyEndorsementPolicy();
ep.addOrgs(ENDORSER_ROLES.MEMBER, 'Org1MSP', 'Org3MSP');
ep.addOrgs(ENDORSER_ROLES.PEER, 'Org2MSP');
Expand Down
34 changes: 20 additions & 14 deletions libraries/fabric-shim/test/unit/handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -900,42 +900,48 @@ describe('Handler', () => {
});

describe('handleGetMultipleStates', () => {
let handleGetStateStub;
afterEach(() => {
sandbox.restore();
});

it('should stub handleGetState and return buffered values', async () => {
it('should send a GET_STATE_MULTIPLE message to the peer and return values', async () => {
const mockStream = {write: sinon.stub(), end: sinon.stub()};
const handler = new Handler.ChaincodeMessageHandler(mockStream, mockChaincodeImpl);
handleGetStateStub = sandbox.stub(handler, 'handleGetState').resolves(Buffer.from('value'));
const _askPeerAndListenStub = sandbox.stub(handler, '_askPeerAndListen').resolves({ payload: Buffer.alloc(0) });

const result = await handler.handleGetMultipleStates(['key1', 'key2'], 'theChannelID', 'theTxID');

expect(result).to.deep.equal([Buffer.from('value'), Buffer.from('value')]);
expect(handleGetStateStub.calledTwice).to.be.true;
expect(handleGetStateStub.firstCall.args).to.deep.equal(['', 'key1', 'theChannelID', 'theTxID']);
expect(handleGetStateStub.secondCall.args).to.deep.equal(['', 'key2', 'theChannelID', 'theTxID']);
expect(result).to.deep.equal([]);
expect(_askPeerAndListenStub.calledOnce).to.be.true;
expect(_askPeerAndListenStub.firstCall.args[1]).to.deep.equal('GET_STATE_MULTIPLE');
const sentMsg = _askPeerAndListenStub.firstCall.args[0];
expect(sentMsg.getType()).to.equal(peer.ChaincodeMessage.Type.GET_STATE_MULTIPLE);
const decodedPayload = peer.GetStateMultiple.deserializeBinary(sentMsg.getPayload_asU8());
expect(decodedPayload.getKeysList()).to.deep.equal(['key1', 'key2']);
expect(decodedPayload.getCollection()).to.equal('');
});
});

describe('handleGetMultiplePrivateData', () => {
let handleGetStateStub;
afterEach(() => {
sandbox.restore();
});

it('should stub handleGetState and return buffered values', async () => {
it('should send a GET_STATE_MULTIPLE message with a collection to the peer and return values', async () => {
const mockStream = {write: sinon.stub(), end: sinon.stub()};
const handler = new Handler.ChaincodeMessageHandler(mockStream, mockChaincodeImpl);
handleGetStateStub = sandbox.stub(handler, 'handleGetState').resolves(Buffer.from('value'));
const _askPeerAndListenStub = sandbox.stub(handler, '_askPeerAndListen').resolves({ payload: Buffer.alloc(0) });

const result = await handler.handleGetMultiplePrivateData('collection1', ['key1', 'key2'], 'theChannelID', 'theTxID');

expect(result).to.deep.equal([Buffer.from('value'), Buffer.from('value')]);
expect(handleGetStateStub.calledTwice).to.be.true;
expect(handleGetStateStub.firstCall.args).to.deep.equal(['collection1', 'key1', 'theChannelID', 'theTxID']);
expect(handleGetStateStub.secondCall.args).to.deep.equal(['collection1', 'key2', 'theChannelID', 'theTxID']);
expect(result).to.deep.equal([]);
expect(_askPeerAndListenStub.calledOnce).to.be.true;
expect(_askPeerAndListenStub.firstCall.args[1]).to.deep.equal('GET_STATE_MULTIPLE');
const sentMsg = _askPeerAndListenStub.firstCall.args[0];
expect(sentMsg.getType()).to.equal(peer.ChaincodeMessage.Type.GET_STATE_MULTIPLE);
const decodedPayload = peer.GetStateMultiple.deserializeBinary(sentMsg.getPayload_asU8());
expect(decodedPayload.getKeysList()).to.deep.equal(['key1', 'key2']);
expect(decodedPayload.getCollection()).to.equal('collection1');
});
});

Expand Down
32 changes: 32 additions & 0 deletions libraries/fabric-shim/test/unit/stub.js
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,38 @@ describe('Stub', () => {
});
});

describe('getMultipleStates', () => {
it('should call handler.handleGetMultipleStates with the keys array', async () => {
const handleGetMultipleStatesStub = sinon.stub().resolves([Buffer.from('dummy')]);

const stub = new Stub({
handleGetMultipleStates: handleGetMultipleStatesStub
}, 'dummyChannelId', 'dummyTxid', chaincodeInput);

const result = await stub.getMultipleStates(['key1', 'key2']);

expect(result).to.deep.equal([Buffer.from('dummy')]);
sinon.assert.calledOnce(handleGetMultipleStatesStub);
sinon.assert.calledWith(handleGetMultipleStatesStub, ['key1', 'key2'], 'dummyChannelId', 'dummyTxid');
});
});

describe('getMultiplePrivateData', () => {
it('should call handler.handleGetMultiplePrivateData with the collection and keys array', async () => {
const handleGetMultiplePrivateDataStub = sinon.stub().resolves([Buffer.from('dummy')]);

const stub = new Stub({
handleGetMultiplePrivateData: handleGetMultiplePrivateDataStub
}, 'dummyChannelId', 'dummyTxid', chaincodeInput);

const result = await stub.getMultiplePrivateData('myCollection', ['key1', 'key2']);

expect(result).to.deep.equal([Buffer.from('dummy')]);
sinon.assert.calledOnce(handleGetMultiplePrivateDataStub);
sinon.assert.calledWith(handleGetMultiplePrivateDataStub, 'myCollection', ['key1', 'key2'], 'dummyChannelId', 'dummyTxid');
});
});

describe('putState', () => {
it ('should return handler.handlePutState', async () => {
const handlePutStateStub = sinon.stub().resolves('some state');
Expand Down
Loading