From f499e22717dea5fd7a303b4e6654f7d92ce7cb94 Mon Sep 17 00:00:00 2001 From: Simon Stone Date: Mon, 2 Sep 2019 15:37:52 +0100 Subject: [PATCH] [FAB-16496] Port to protobufjs 6 - Use protobufjs 6 for message handling - Use @grpc/proto-loader and grpc for RPC Signed-off-by: Simon Stone Change-Id: I5916fb0f14c6159f7b569b9ad5900b433df8624b --- .eslintignore | 1 + .../docker-compose/docker-compose-base.yaml | 1 - fabric-shim-crypto/lib/enc-sign.js | 8 +- fabric-shim-crypto/test/shim-crypto.js | 28 +- fabric-shim/lib/chaincode.js | 49 ++-- fabric-shim/lib/handler.js | 217 ++++++--------- fabric-shim/lib/iterators.js | 19 +- fabric-shim/lib/stub.js | 76 ++---- fabric-shim/lib/utils/statebased.js | 71 +++-- fabric-shim/package-lock.json | 6 +- fabric-shim/test/typescript/chaincode.ts | 4 +- fabric-shim/test/unit/chaincode.js | 44 +-- fabric-shim/test/unit/client-identity.js | 12 +- .../contract-spi/chaincodefromcontract.js | 50 ++-- fabric-shim/test/unit/handler.js | 252 +++++------------- fabric-shim/test/unit/iterators.js | 6 +- fabric-shim/test/unit/stub.js | 161 ++++------- fabric-shim/test/unit/utils/statebased.js | 25 +- fabric-shim/types/index.d.ts | 4 +- test/fv/crud.js | 8 +- 20 files changed, 343 insertions(+), 699 deletions(-) create mode 100644 .eslintignore diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..0e804e3a --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +bundle.js diff --git a/build/test/network/docker-compose/docker-compose-base.yaml b/build/test/network/docker-compose/docker-compose-base.yaml index 5a58a941..c3f0f194 100644 --- a/build/test/network/docker-compose/docker-compose-base.yaml +++ b/build/test/network/docker-compose/docker-compose-base.yaml @@ -120,7 +120,6 @@ services: - /var/run/:/host/var/run/ - ../../../../test:/opt/gopath/src/github.com/chaincode - ../crypto-material/:/etc/hyperledger/configtx/ - - ../crypto-material:/etc/hyperledger/config - ../../../../test/fixtures:/etc/hyperledger/fixtures couchdb: diff --git a/fabric-shim-crypto/lib/enc-sign.js b/fabric-shim-crypto/lib/enc-sign.js index 6b677c00..eb4fd100 100644 --- a/fabric-shim-crypto/lib/enc-sign.js +++ b/fabric-shim-crypto/lib/enc-sign.js @@ -40,18 +40,16 @@ class ChaincodeCryptoLibrary { if (!iv) { // transaction proposal did not include an IV, generate one iv = crypto.randomBytes(16); - } else { // 128-bit IV for AES (block size) - iv = iv.toBuffer(); } if (key) { - this.cipher = crypto.createCipheriv(ALGORITHM, key.toBuffer(), iv); - this.decipher = crypto.createDecipheriv(ALGORITHM, key.toBuffer(), iv); + this.cipher = crypto.createCipheriv(ALGORITHM, key, iv); + this.decipher = crypto.createDecipheriv(ALGORITHM, key, iv); } const signKey = tmap.get(SIGN_KEY); if (signKey) { - this.signKey = importKey(signKey.toBuffer()); + this.signKey = importKey(signKey); this._ecdsa = new EC(elliptic.curves.p256); } } diff --git a/fabric-shim-crypto/test/shim-crypto.js b/fabric-shim-crypto/test/shim-crypto.js index 0cd6777e..fa91ad31 100644 --- a/fabric-shim-crypto/test/shim-crypto.js +++ b/fabric-shim-crypto/test/shim-crypto.js @@ -21,29 +21,17 @@ const ECDSAKey = ShimCrypto.__get__('ECDSAKey'); const mapItems = {}; mapItems.iv = { key: INIT_VECTOR, - value: { - toBuffer: () => { - return Buffer.from('0123456789012345'); - } - } + value: Buffer.from('0123456789012345') }; mapItems.encryptKey = { key: ENCRYPT_KEY, - value: { - toBuffer: () => { - return Buffer.from('01234567890123456789012345678901'); - } - } + value: Buffer.from('01234567890123456789012345678901') }; mapItems.signKey = { key: SIGN_KEY, - value: { - toBuffer: () => { - return Buffer.from('some signKey'); - } - } + value: Buffer.from('some signKey') }; const saveImportKey = ShimCrypto.__get__('importKey'); @@ -84,9 +72,9 @@ describe('enc-sign', () => { expect(sc._ecdsa).to.be.undefined; expect(mockCreateCipher.calledOnce).to.be.ok; - expect(mockCreateCipher.firstCall.args).to.deep.equal([ALGORITHM, mapItems.encryptKey.value.toBuffer(), mapItems.iv.value.toBuffer()]); + expect(mockCreateCipher.firstCall.args).to.deep.equal([ALGORITHM, mapItems.encryptKey.value, mapItems.iv.value]); expect(mockCreateDecipher.calledOnce).to.be.ok; - expect(mockCreateDecipher.firstCall.args).to.deep.equal([ALGORITHM, mapItems.encryptKey.value.toBuffer(), mapItems.iv.value.toBuffer()]); + expect(mockCreateDecipher.firstCall.args).to.deep.equal([ALGORITHM, mapItems.encryptKey.value, mapItems.iv.value]); }); it ('should set key values when init vector not in map', () => { @@ -105,9 +93,9 @@ describe('enc-sign', () => { expect(mockRandomBytes.calledOnce).to.be.ok; expect(mockRandomBytes.firstCall.args).to.deep.equal([16]); expect(mockCreateCipher.calledOnce).to.be.ok; - expect(mockCreateCipher.firstCall.args).to.deep.equal([ALGORITHM, mapItems.encryptKey.value.toBuffer(), 'some random bytes']); + expect(mockCreateCipher.firstCall.args).to.deep.equal([ALGORITHM, mapItems.encryptKey.value, 'some random bytes']); expect(mockCreateDecipher.calledOnce).to.be.ok; - expect(mockCreateDecipher.firstCall.args).to.deep.equal([ALGORITHM, mapItems.encryptKey.value.toBuffer(), 'some random bytes']); + expect(mockCreateDecipher.firstCall.args).to.deep.equal([ALGORITHM, mapItems.encryptKey.value, 'some random bytes']); }); it ('should set sign key values', () => { @@ -121,7 +109,7 @@ describe('enc-sign', () => { expect(sc._ecdsa).to.deep.equal(ecStubInstance); expect(mockImportKey.calledOnce).to.be.ok; - expect(mockImportKey.firstCall.args).to.deep.equal([mapItems.signKey.value.toBuffer()]); + expect(mockImportKey.firstCall.args).to.deep.equal([mapItems.signKey.value]); expect(mockEC.calledOnce).to.be.ok; expect(mockEC.firstCall.args).to.deep.equal([elliptic.curves.p256]); diff --git a/fabric-shim/lib/chaincode.js b/fabric-shim/lib/chaincode.js index 5e54102e..8f9d058a 100644 --- a/fabric-shim/lib/chaincode.js +++ b/fabric-shim/lib/chaincode.js @@ -6,8 +6,7 @@ /* eslint-disable no-useless-escape */ 'use strict'; -const ProtoLoader = require('./protoloader'); -const path = require('path'); +const fabprotos = require('../bundle'); const util = require('util'); const {Certificate} = require('@fidm/x509'); const Logger = require('./logger'); @@ -25,21 +24,6 @@ const StartCommand = require('./cmds/startCommand.js'); const yargs = require('yargs'); -const _chaincodeProto = ProtoLoader.load({ - root: path.join(__dirname, './protos'), - file: 'peer/chaincode.proto' -}).protos; - -const _serviceProto = ProtoLoader.load({ - root: path.join(__dirname, './protos'), - file: 'peer/chaincode_shim.proto' -}).protos; - -const _responseProto = ProtoLoader.load({ - root: path.join(__dirname, './protos'), - file: 'peer/proposal_response.proto' -}).protos; - /** * Chaincodes must implement the methods in this interface. The Init() method is called during * chaincode instantiation or upgrade to preform any necessary intitialization @@ -138,14 +122,15 @@ class Shim { const chaincodeName = opts['chaincode-id-name']; const client = new Handler(chaincode, url, optsCpy); - const chaincodeID = new _chaincodeProto.ChaincodeID(); - chaincodeID.setName(chaincodeName); + const chaincodeID = { + name: chaincodeName + }; logger.info(util.format('Registering with peer %s as chaincode "%s"', opts['peer.address'], chaincodeName)); client.chat({ - type: _serviceProto.ChaincodeMessage.Type.REGISTER, - payload: chaincodeID.toBuffer() + type: fabprotos.protos.ChaincodeMessage.Type.REGISTER, + payload: fabprotos.protos.ChaincodeID.encode(chaincodeID).finish() }); // return the client object to give the calling code @@ -168,11 +153,10 @@ class Shim { * @returns {SuccessResponse} */ static success(payload) { - const ret = new _responseProto.Response(); - ret.status = ChaincodeStub.RESPONSE_CODE.OK; - ret.payload = payload ? payload : Buffer.from(''); - - return ret; + return { + status: ChaincodeStub.RESPONSE_CODE.OK, + payload: payload ? payload : Buffer.from('') + }; } /** @@ -190,11 +174,10 @@ class Shim { * @returns {ErrorResponse} */ static error(msg) { - const ret = new _responseProto.Response(); - ret.status = ChaincodeStub.RESPONSE_CODE.ERROR; - ret.message = msg; - - return ret; + return { + status: ChaincodeStub.RESPONSE_CODE.ERROR, + message: msg + }; } /** @@ -245,9 +228,9 @@ class ClientIdentity { this.stub = stub; const signingId = stub.getCreator(); - this.mspId = signingId.getMspid(); + this.mspId = signingId.mspid; - this.idBytes = signingId.getIdBytes().toBuffer(); + this.idBytes = signingId.idBytes; const normalizedCert = normalizeX509(this.idBytes.toString(), loggerPrefix); // assemble the unique ID based on certificate diff --git a/fabric-shim/lib/handler.js b/fabric-shim/lib/handler.js index 04c09a0f..98ed6733 100644 --- a/fabric-shim/lib/handler.js +++ b/fabric-shim/lib/handler.js @@ -8,10 +8,11 @@ /* eslint-disable no-useless-escape */ process.env.GRPC_SSL_CIPHER_SUITES = 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384'; +const protoLoader = require('@grpc/proto-loader'); const grpc = require('grpc'); -const ProtoLoader = require('./protoloader'); -const {URL} = require('url'); +const fabprotos = require('../bundle'); const path = require('path'); +const {URL} = require('url'); const util = require('util'); const StateQueryIterator = require('./iterators').StateQueryIterator; const HistoryQueryIterator = require('./iterators').HistoryQueryIterator; @@ -21,21 +22,6 @@ const Stub = require('./stub.js'); const utils = require('./utils/utils'); -const _serviceProto = ProtoLoader.load({ - root: path.join(__dirname, './protos'), - file: 'peer/chaincode_shim.proto' -}).protos; - -const _chaincodeProto = ProtoLoader.load({ - root: path.join(__dirname, './protos'), - file: 'peer/chaincode.proto' -}).protos; - -const _responseProto = ProtoLoader.load({ - root: path.join(__dirname, './protos'), - file: 'peer/proposal_response.proto' -}).protos; - const STATES = { Created: 'created', Established: 'established', @@ -53,6 +39,23 @@ const MSG_TYPE = { COMPLETED: 'COMPLETED', // _serviceProto.ChaincodeMessage.Type.COMPLETED }; +const PROTO_PATH = path.resolve(__dirname, '..', 'protos', 'peer', 'chaincode_shim.proto'); +const packageDefinition = protoLoader.loadSync( + PROTO_PATH, + { + keepCase: true, + longs: String, + enums: String, + defaults: true, + oneofs: true, + includeDirs: [ + path.resolve(__dirname, '..', 'google-protos'), + path.resolve(__dirname, '..', 'protos') + ] + } +); +const protoDescriptor = grpc.loadPackageDefinition(packageDefinition); + /* * Simple class to represent a message to be queued with the associated * promise methods to be driven around this message @@ -259,7 +262,7 @@ class ChaincodeSupportClient { this._request_timeout = opts['request-timeout']; } - this._client = new _serviceProto.ChaincodeSupport(this._endpoint.addr, this._endpoint.creds, this._options); + this._client = new protoDescriptor.protos.ChaincodeSupport(this._endpoint.addr, this._endpoint.creds, this._options); } close() { @@ -362,13 +365,9 @@ class ChaincodeSupportClient { } async handleGetState(collection, key, channel_id, txId) { - const payload = new _serviceProto.GetState(); - payload.setKey(key); - payload.setCollection(collection); - const msg = { - type: _serviceProto.ChaincodeMessage.Type.GET_STATE, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.GET_STATE, + payload: fabprotos.protos.GetState.encode({key, collection}).finish(), txid: txId, channel_id: channel_id }; @@ -377,114 +376,76 @@ class ChaincodeSupportClient { } async handlePutState(collection, key, value, channel_id, txId) { - const payload = new _serviceProto.PutState(); - payload.setKey(key); - payload.setValue(value); - payload.setCollection(collection); - const msg = { - type: _serviceProto.ChaincodeMessage.Type.PUT_STATE, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.PUT_STATE, + payload: fabprotos.protos.PutState.encode({key, value, collection}).finish(), txid: txId, channel_id: channel_id }; - return await this._askPeerAndListen(msg, 'PutState'); } async handleDeleteState(collection, key, channel_id, txId) { - const payload = new _serviceProto.DelState(); - payload.setKey(key); - payload.setCollection(collection); - const msg = { - type: _serviceProto.ChaincodeMessage.Type.DEL_STATE, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.DEL_STATE, + payload: fabprotos.protos.DelState.encode({key, collection}).finish(), txid: txId, channel_id: channel_id }; - return await this._askPeerAndListen(msg, 'DeleteState'); } async handlePutStateMetadata(collection, key, metakey, ep, channel_id, txId) { - // construct payload for PutStateMetadata - const stateMetadata = new _serviceProto.StateMetadata(); - stateMetadata.setMetakey(metakey); - stateMetadata.setValue(ep); - - const payload = new _serviceProto.PutStateMetadata(); - payload.setKey(key); - payload.setCollection(collection); - payload.setMetadata(stateMetadata); - const msg = { - type: _serviceProto.ChaincodeMessage.Type.PUT_STATE_METADATA, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.PUT_STATE_METADATA, + payload: fabprotos.protos.PutStateMetadata.encode({ + key, + collection, + metadata: { + metakey, + value: ep + } + }).finish(), txid: txId, channel_id: channel_id }; - return this._askPeerAndListen(msg, 'PutStateMetadata'); } async handleGetPrivateDataHash(collection, key, channel_id, txId) { - const payload = new _serviceProto.GetState(); - payload.setKey(key); - payload.setCollection(collection); - const msg = { - type: _serviceProto.ChaincodeMessage.Type.GET_PRIVATE_DATA_HASH, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.GET_PRIVATE_DATA_HASH, + payload: fabprotos.protos.GetState.encode({key, collection}).finish(), txid: txId, channel_id: channel_id }; - return await this._askPeerAndListen(msg, 'GetPrivateDataHash'); } async handleGetStateMetadata(collection, key, channel_id, txId) { - // construct payload for GetStateMetadata - const payload = new _serviceProto.GetStateMetadata(); - payload.setKey(key); - payload.setCollection(collection); - const msg = { - type: _serviceProto.ChaincodeMessage.Type.GET_STATE_METADATA, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.GET_STATE_METADATA, + payload: fabprotos.protos.GetStateMetadata.encode({key, collection}).finish(), txid: txId, channel_id: channel_id }; - return this._askPeerAndListen(msg, 'GetStateMetadata'); } async handleGetStateByRange(collection, startKey, endKey, channel_id, txId, metadata) { - const payload = new _serviceProto.GetStateByRange(); - payload.setStartKey(startKey); - payload.setEndKey(endKey); - payload.setCollection(collection); - if (metadata) { - payload.setMetadata(metadata); - } - const msg = { - type: _serviceProto.ChaincodeMessage.Type.GET_STATE_BY_RANGE, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.GET_STATE_BY_RANGE, + payload: fabprotos.protos.GetStateByRange.encode({startKey, endKey, collection, metadata}).finish(), txid: txId, channel_id: channel_id }; - return await this._askPeerAndListen(msg, 'GetStateByRange'); } async handleQueryStateNext(id, channel_id, txId) { - const payload = new _serviceProto.QueryStateNext(); - payload.setId(id); - const msg = { - type: _serviceProto.ChaincodeMessage.Type.QUERY_STATE_NEXT, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.QUERY_STATE_NEXT, + payload: fabprotos.protos.QueryStateNext.encode({id}).finish(), txid: txId, channel_id }; @@ -492,12 +453,9 @@ class ChaincodeSupportClient { } async handleQueryStateClose(id, channel_id, txId) { - const payload = new _serviceProto.QueryStateClose(); - payload.setId(id); - const msg = { - type: _serviceProto.ChaincodeMessage.Type.QUERY_STATE_CLOSE, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.QUERY_STATE_CLOSE, + payload: fabprotos.protos.QueryStateClose.encode({id}).finish(), txid: txId, channel_id: channel_id }; @@ -505,16 +463,9 @@ class ChaincodeSupportClient { } async handleGetQueryResult(collection, query, metadata, channel_id, txId) { - const payload = new _serviceProto.GetQueryResult(); - payload.setQuery(query); - payload.setCollection(collection); - if (metadata) { - payload.setMetadata(metadata); - } - const msg = { - type: _serviceProto.ChaincodeMessage.Type.GET_QUERY_RESULT, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.GET_QUERY_RESULT, + payload: fabprotos.protos.GetQueryResult.encode({query, collection, metadata}).finish(), txid: txId, channel_id: channel_id }; @@ -522,12 +473,9 @@ class ChaincodeSupportClient { } async handleGetHistoryForKey(key, channel_id, txId) { - const payload = new _serviceProto.GetHistoryForKey(); - payload.setKey(key); - const msg = { - type: _serviceProto.ChaincodeMessage.Type.GET_HISTORY_FOR_KEY, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.GET_HISTORY_FOR_KEY, + payload: fabprotos.protos.GetHistoryForKey.encode({key}).finish(), txid: txId, channel_id: channel_id }; @@ -535,21 +483,17 @@ class ChaincodeSupportClient { } async handleInvokeChaincode(chaincodeName, args, channel_id, txId) { - const payload = new _chaincodeProto.ChaincodeSpec(); - const chaincodeId = new _chaincodeProto.ChaincodeID(); - const chaincodeInput = new _chaincodeProto.ChaincodeInput(); - chaincodeId.setName(chaincodeName); - const inputArgs = []; - args.forEach((arg) => { - inputArgs.push(Buffer.from(arg, 'utf8')); - }); - chaincodeInput.setArgs(inputArgs); - payload.setChaincodeId(chaincodeId); - payload.setInput(chaincodeInput); - + const argsAsBuffers = args.map((arg) => Buffer.from(arg, 'utf8')); const msg = { - type: _serviceProto.ChaincodeMessage.Type.INVOKE_CHAINCODE, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.INVOKE_CHAINCODE, + payload: fabprotos.protos.ChaincodeSpec.encode({ + chaincodeId: { + name: chaincodeName + }, + input: { + args: argsAsBuffers + } + }).finish(), txid: txId, channel_id: channel_id }; @@ -557,12 +501,12 @@ class ChaincodeSupportClient { const message = await this._askPeerAndListen(msg, 'InvokeChaincode'); // here the message type comes back as an enumeration value rather than a string // so need to use the enumerated value - if (message.type === _serviceProto.ChaincodeMessage.Type.COMPLETED) { - return _responseProto.Response.decode(message.payload); + if (message.type === fabprotos.protos.ChaincodeMessage.Type.COMPLETED) { + return fabprotos.protos.Response.decode(message.payload); } // Catch the transaction and rethrow the data - if (message.type === _serviceProto.ChaincodeMessage.Type.ERROR) { + if (message.type === fabprotos.protos.ChaincodeMessage.Type.ERROR) { const errorData = message.payload.toString('utf8'); throw new Error(errorData); } @@ -601,11 +545,11 @@ async function handleMessage(msg, client, action) { let nextStateMsg, input; try { - input = _chaincodeProto.ChaincodeInput.decode(msg.payload); + input = fabprotos.protos.ChaincodeInput.decode(msg.payload); } catch (err) { logger.error('%s Incorrect payload format. Sending ERROR message back to peer', loggerPrefix); nextStateMsg = { - type: _serviceProto.ChaincodeMessage.Type.ERROR, + type: fabprotos.protos.ChaincodeMessage.Type.ERROR, payload: msg.payload, txid: msg.txid, channel_id : msg.channel_id @@ -619,7 +563,7 @@ async function handleMessage(msg, client, action) { } catch (err) { logger.error(util.format('Failed to construct a chaincode stub instance from the INIT message: %s', err)); nextStateMsg = { - type: _serviceProto.ChaincodeMessage.Type.ERROR, + type: fabprotos.protos.ChaincodeMessage.Type.ERROR, payload: Buffer.from(err.toString()), txid: msg.txid, channel_id : msg.channel_id @@ -642,9 +586,10 @@ async function handleMessage(msg, client, action) { loggerPrefix, method); logger.error(errMsg); - resp = new _responseProto.Response(); - resp.status = Stub.RESPONSE_CODE.ERROR; - resp.message = errMsg; + resp = { + status: Stub.RESPONSE_CODE.ERROR, + message: errMsg + }; } logger.debug(util.format( @@ -659,7 +604,7 @@ async function handleMessage(msg, client, action) { logger.error(errMsg); nextStateMsg = { - type: _serviceProto.ChaincodeMessage.Type.ERROR, + type: fabprotos.protos.ChaincodeMessage.Type.ERROR, payload: Buffer.from('' + resp.message), txid: msg.txid, channel_id: msg.channel_id @@ -669,8 +614,8 @@ async function handleMessage(msg, client, action) { loggerPrefix, method)); nextStateMsg = { - type: _serviceProto.ChaincodeMessage.Type.COMPLETED, - payload: resp.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.COMPLETED, + payload: fabprotos.protos.Response.encode(resp).finish(), txid: msg.txid, channel_id: msg.channel_id, chaincode_event: stub.chaincodeEvent @@ -711,14 +656,14 @@ function newErrorMsg(msg, state) { } function handleGetQueryResult(handler, res, method) { - const payload = _serviceProto.QueryResponse.decode(res.payload); + const payload = fabprotos.protos.QueryResponse.decode(res.payload); const iterator = new StateQueryIterator(handler, res.channel_id, res.txid, payload); const result = {iterator}; if (payload.metadata) { logger.debug(util.format('Received metadata for method: %s', method)); - const metadata = _serviceProto.QueryResponseMetadata.decode(payload.metadata); + const metadata = fabprotos.protos.QueryResponseMetadata.decode(payload.metadata); result.metadata = metadata; logger.debug(util.format('metadata: %j', result.metadata)); } @@ -729,13 +674,13 @@ function handleGetQueryResult(handler, res, method) { function handleGetStateMetadata(payload) { const method = 'handleGetStateMetadata'; logger.debug('%s - get response from peer.', method); - const decoded = _serviceProto.StateMetadataResult.decode(payload); + const decoded = fabprotos.protos.StateMetadataResult.decode(payload); logger.debug('%s - decoded response:%j', method, decoded); - const entries = decoded.getEntries(); + const entries = decoded.entries; const metadata = {}; entries.forEach(entry => { - metadata[entry.getMetakey()] = entry.getValue(); + metadata[entry.metakey] = entry.value; }); logger.debug('%s - metadata: %j', method, metadata); @@ -755,12 +700,12 @@ function parseResponse(handler, res, method) { case 'GetQueryResult': return handleGetQueryResult(handler, res, method); case 'GetHistoryForKey': - return new HistoryQueryIterator(handler, res.channel_id, res.txid, _serviceProto.QueryResponse.decode(res.payload)); + return new HistoryQueryIterator(handler, res.channel_id, res.txid, fabprotos.protos.QueryResponse.decode(res.payload)); case 'QueryStateNext': case 'QueryStateClose': - return _serviceProto.QueryResponse.decode(res.payload); + return fabprotos.protos.QueryResponse.decode(res.payload); case 'InvokeChaincode': - return _serviceProto.ChaincodeMessage.decode(res.payload); + return fabprotos.protos.ChaincodeMessage.decode(res.payload); case 'GetStateMetadata': return handleGetStateMetadata(res.payload); } diff --git a/fabric-shim/lib/iterators.js b/fabric-shim/lib/iterators.js index 44304a8c..6e67c613 100644 --- a/fabric-shim/lib/iterators.js +++ b/fabric-shim/lib/iterators.js @@ -1,12 +1,13 @@ +/* +# Copyright Zhao Chaoyi. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +*/ + 'use strict'; -const ProtoLoader = require('./protoloader'); -const path = require('path'); -const logger = require('./logger').getLogger('lib/iterators.js'); -const _queryresultProto = ProtoLoader.load({ - root: path.join(__dirname, './protos'), - file: 'ledger/queryresult/kv_query_result.proto' -}).queryresult; +const fabprotos = require('../bundle'); +const logger = require('./logger').getLogger('lib/iterators.js'); /** * CommonIterator allows a chaincode to check whether any more result(s) @@ -50,9 +51,9 @@ class CommonIterator { */ _getResultFromBytes(bytes) { if (this.type === 'QUERY') { - return _queryresultProto.KV.decode(bytes.resultBytes); + return fabprotos.queryresult.KV.decode(bytes.resultBytes); } else if (this.type === 'HISTORY') { - return _queryresultProto.KeyModification.decode(bytes.resultBytes); + return fabprotos.queryresult.KeyModification.decode(bytes.resultBytes); } throw new Error('Iterator constructed with unknown type: ' + this.type); } diff --git a/fabric-shim/lib/stub.js b/fabric-shim/lib/stub.js index 9b219c8e..85c4265e 100644 --- a/fabric-shim/lib/stub.js +++ b/fabric-shim/lib/stub.js @@ -7,36 +7,10 @@ // TODO: Need to add parameter validation to all calls. 'use strict'; -const ProtoLoader = require('./protoloader'); -const path = require('path'); +const fabprotos = require('../bundle'); const util = require('util'); const crypto = require('crypto'); -const _commonProto = ProtoLoader.load({ - root: path.join(__dirname, './protos'), - file: 'common/common.proto' -}).common; - -const _proposalProto = ProtoLoader.load({ - root: path.join(__dirname, './protos'), - file: 'peer/proposal.proto' -}).protos; - -const _eventProto = ProtoLoader.load({ - root: path.join(__dirname, './protos'), - file: 'peer/chaincode_event.proto' -}).protos; - -const _idProto = ProtoLoader.load({ - root: path.join(__dirname, './protos'), - file: 'msp/identities.proto' -}).msp; - -const _serviceProto = ProtoLoader.load({ - root: path.join(__dirname, './protos'), - file: 'peer/chaincode_shim.proto' -}).protos; - const logger = require('./logger').getLogger('lib/stub.js'); const VALIDATION_PARAMETER = 'VALIDATION_PARAMETER'; @@ -77,9 +51,9 @@ function validateSimpleKeys(...keys) { } function computeProposalBinding(decodedSP) { - const nonce = decodedSP.proposal.header.signature_header.nonce; - const creator = decodedSP.proposal.header.signature_header.creator.toBuffer(); - const epoch = decodedSP.proposal.header.channel_header.epoch; + const nonce = decodedSP.proposal.header.signatureHeader.nonce; + const creator = fabprotos.msp.SerializedIdentity.encode(decodedSP.proposal.header.signatureHeader.creator).finish(); + const epoch = decodedSP.proposal.header.channelHeader.epoch; // see github.com/hyperledger/fabric/protos/utils/proputils.go, computeProposalBindingInternal() @@ -99,10 +73,7 @@ function computeProposalBinding(decodedSP) { // Construct the QueryMetadata with a page size and a bookmark needed for pagination function createQueryMetadata(pageSize, bookmark) { - const metadata = new _serviceProto.QueryMetadata(); - metadata.setPageSize(pageSize); - metadata.setBookmark(bookmark); - return metadata.toBuffer(); + return fabprotos.protos.QueryMetadata.encode({pageSize, bookmark}).finish(); } // function to convert a promise that either will resolve to an iterator or an object @@ -161,13 +132,8 @@ class ChaincodeStub { constructor(client, channel_id, txId, chaincodeInput, signedProposal) { this.channel_id = channel_id; this.txId = txId; - this.args = chaincodeInput.args.map((entry) => { - return entry.toBuffer().toString(); - }); - - this.bufferArgs = chaincodeInput.args.map((entry) => { - return entry.toBuffer(); - }); + this.bufferArgs = chaincodeInput.args.map((arg) => Buffer.from(arg)); + this.args = this.bufferArgs.map((arg) => arg.toString()); this.handler = client; this.validationParameterMetakey = VALIDATION_PARAMETER; @@ -179,24 +145,24 @@ class ChaincodeStub { let proposal; try { - proposal = _proposalProto.Proposal.decode(signedProposal.proposal_bytes); + proposal = fabprotos.protos.Proposal.decode(signedProposal.proposal_bytes); decodedSP.proposal = {}; this.proposal = proposal; } catch (err) { throw new Error(util.format('Failed extracting proposal from signedProposal. [%s]', err)); } - if (!this.proposal.header || this.proposal.header.toBuffer().length === 0) { + if (!this.proposal.header || this.proposal.header.length === 0) { throw new Error('Proposal header is empty'); } - if (!this.proposal.payload || this.proposal.payload.toBuffer().length === 0) { + if (!this.proposal.payload || this.proposal.payload.length === 0) { throw new Error('Proposal payload is empty'); } let header; try { - header = _commonProto.Header.decode(this.proposal.header); + header = fabprotos.common.Header.decode(this.proposal.header); decodedSP.proposal.header = {}; } catch (err) { throw new Error(util.format('Could not extract the header from the proposal: %s', err)); @@ -204,15 +170,15 @@ class ChaincodeStub { let signatureHeader; try { - signatureHeader = _commonProto.SignatureHeader.decode(header.signature_header); - decodedSP.proposal.header.signature_header = {nonce: signatureHeader.getNonce().toBuffer()}; + signatureHeader = fabprotos.common.SignatureHeader.decode(header.signatureHeader); + decodedSP.proposal.header.signature_header = {nonce: signatureHeader.nonce}; } catch (err) { throw new Error(util.format('Decoding SignatureHeader failed: %s', err)); } let creator; try { - creator = _idProto.SerializedIdentity.decode(signatureHeader.creator); + creator = fabprotos.msp.SerializedIdentity.decode(signatureHeader.creator); decodedSP.proposal.header.signature_header.creator = creator; this.creator = creator; } catch (err) { @@ -221,7 +187,7 @@ class ChaincodeStub { let channelHeader; try { - channelHeader = _commonProto.ChannelHeader.decode(header.channel_header); + channelHeader = fabprotos.common.ChannelHeader.decode(header.channelHeader); decodedSP.proposal.header.channel_header = channelHeader; this.txTimestamp = channelHeader.timestamp; } catch (err) { @@ -230,13 +196,13 @@ class ChaincodeStub { let ccpp; try { - ccpp = _proposalProto.ChaincodeProposalPayload.decode(this.proposal.payload); + ccpp = fabprotos.protos.ChaincodeProposalPayload.decode(this.proposal.payload); decodedSP.proposal.payload = ccpp; } catch (err) { throw new Error(util.format('Decoding ChaincodeProposalPayload failed: %s', err)); } - this.transientMap = ccpp.getTransientMap(); + this.transientMap = new Map(Object.entries(ccpp.TransientMap)); this.signedProposal = decodedSP; @@ -768,10 +734,10 @@ class ChaincodeStub { throw new Error('Event name must be a non-empty string'); } - const event = new _eventProto.ChaincodeEvent(); - event.setEventName(name); - event.setPayload(payload); - this.chaincodeEvent = event; + this.chaincodeEvent = { + eventName: name, + payload + }; } /** diff --git a/fabric-shim/lib/utils/statebased.js b/fabric-shim/lib/utils/statebased.js index cf4a7a9d..0c0a96d1 100644 --- a/fabric-shim/lib/utils/statebased.js +++ b/fabric-shim/lib/utils/statebased.js @@ -4,18 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 */ -const ProtoLoader = require('../protoloader'); -const path = require('path'); - -const _policiesProto = ProtoLoader.load({ - root: path.join(__dirname, '../protos'), - file: 'common/policies.proto' -}).common; - -const _principalProto = ProtoLoader.load({ - root: path.join(__dirname, '../protos'), - file: 'msp/msp_principal.proto' -}).common; +const fabprotos = require('../../bundle'); const ROLE_TYPE_MEMBER = 'MEMBER'; const ROLE_TYPE_PEER = 'PEER'; @@ -39,7 +28,7 @@ class KeyEndorsementPolicy { constructor(policy) { this.orgs = {}; if (policy) { - const spe = _policiesProto.SignaturePolicyEnvelope.decode(policy); + const spe = fabprotos.common.SignaturePolicyEnvelope.decode(policy); this._setMspIdsFromSPE(spe); } } @@ -50,7 +39,7 @@ class KeyEndorsementPolicy { */ getPolicy() { const spe = this._getPolicyFromMspId(); - return spe.toBuffer(); + return fabprotos.common.SignaturePolicyEnvelope.encode(spe).finish(); } /** @@ -63,10 +52,10 @@ class KeyEndorsementPolicy { let mspRole; switch (role) { case ROLE_TYPE_MEMBER: - mspRole = _principalProto.MSPRole.MSPRoleType.MEMBER; + mspRole = fabprotos.common.MSPRole.MSPRoleType.MEMBER; break; case ROLE_TYPE_PEER: - mspRole = _principalProto.MSPRole.MSPRoleType.PEER; + mspRole = fabprotos.common.MSPRole.MSPRoleType.PEER; break; default: throw new Error(`role type ${role} does not exist`); @@ -106,9 +95,9 @@ class KeyEndorsementPolicy { signaturePolicyEnvelope.identities.forEach(identity => { // this imlementation only supports the ROLE type /* istanbul ignore else */ - if (identity.PrincipalClassification === _principalProto.MSPPrincipal.ROLE) { - const msprole = _principalProto.MSPRole.decode(identity.principal); - this.orgs[msprole.msp_identifier] = msprole.role; + if (identity.principalClassification === fabprotos.common.MSPPrincipal.Classification.ROLE) { + const msprole = fabprotos.common.MSPRole.decode(identity.principal); + this.orgs[msprole.mspIdentifier] = msprole.role; } }); } @@ -123,31 +112,37 @@ class KeyEndorsementPolicy { const principals = []; const sigsPolicies = []; mspIds.forEach((mspId, i) => { - const mspRole = new _principalProto.MSPRole(); - mspRole.setRole(this.orgs[mspId]); - mspRole.setMspIdentifier(mspId); - const principal = new _principalProto.MSPPrincipal(); - principal.setPrincipalClassification(_principalProto.MSPPrincipal.Classification.ROLE); - principal.setPrincipal(mspRole.toBuffer()); + const mspRole = { + role: this.orgs[mspId], + mspIdentifier: mspId + }; + const principal = { + principalClassification: fabprotos.common.MSPPrincipal.Classification.ROLE, + principal: fabprotos.common.MSPRole.encode(mspRole).finish() + }; principals.push(principal); - const signedBy = new _policiesProto.SignaturePolicy(); - signedBy.set('signed_by', i); + const signedBy = { + signedBy: i, + }; sigsPolicies.push(signedBy); }); // create the policy: it requires exactly 1 signature from all of the principals - const allOf = new _policiesProto.SignaturePolicy.NOutOf(); - allOf.setN(mspIds.length); - allOf.setRules(sigsPolicies); - - const noutof = new _policiesProto.SignaturePolicy(); - noutof.set('n_out_of', allOf); - - const spe = new _policiesProto.SignaturePolicyEnvelope(); - spe.setVersion(0); - spe.setRule(noutof); - spe.setIdentities(principals); + const allOf = { + n: mspIds.length, + rules: sigsPolicies + }; + + const noutof = { + nOutOf: allOf + }; + + const spe = { + version: 0, + rule: noutof, + identities: principals + }; return spe; } } diff --git a/fabric-shim/package-lock.json b/fabric-shim/package-lock.json index 2f774bf1..4b129015 100644 --- a/fabric-shim/package-lock.json +++ b/fabric-shim/package-lock.json @@ -934,9 +934,9 @@ "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=" }, "fabric-contract-api": { - "version": "2.0.0-snapshot.91", - "resolved": "https://registry.npmjs.org/fabric-contract-api/-/fabric-contract-api-2.0.0-snapshot.91.tgz", - "integrity": "sha512-c+K6h2WtihDnwUHvPSvl8vLJ3gijHQJmUUu60Grfo7ivyJET4kbANg0clg9Xj9S7e9qtJsFC9vFKmU7EsVq/Lw==", + "version": "2.0.0-snapshot.92", + "resolved": "https://registry.npmjs.org/fabric-contract-api/-/fabric-contract-api-2.0.0-snapshot.92.tgz", + "integrity": "sha512-tQyQegukDac0WfPKwOryKdvseqOdd/B6x8H1qf3h/1RhtAd3YiUsZe1wYFkIFl083yN993sVqMBdrdNxqJNRLg==", "requires": { "get-params": "^0.1.2", "reflect-metadata": "^0.1.12", diff --git a/fabric-shim/test/typescript/chaincode.ts b/fabric-shim/test/typescript/chaincode.ts index ae8095f0..a0261526 100644 --- a/fabric-shim/test/typescript/chaincode.ts +++ b/fabric-shim/test/typescript/chaincode.ts @@ -222,10 +222,8 @@ class TestTS implements ChaincodeInterface { const TxTimestamp: Timestamp = stub.getTxTimestamp(); const creator: SerializedIdentity = stub.getCreator(); - let idbytes: Buffer = creator.getIdBytes(); - idbytes = creator.id_bytes; + let idbytes: Buffer = creator.idBytes; let mspid: string = creator.mspid; - mspid = creator.getMspid(); const invokeChaincode: ChaincodeResponse = await stub.invokeChaincode('ccid', ['bob', 'duck'], 'channelid'); } diff --git a/fabric-shim/test/unit/chaincode.js b/fabric-shim/test/unit/chaincode.js index 6e2b0a98..2701f0cd 100644 --- a/fabric-shim/test/unit/chaincode.js +++ b/fabric-shim/test/unit/chaincode.js @@ -10,19 +10,15 @@ const sinon = require('sinon'); const chai = require('chai'); const expect = chai.expect; const rewire = require('rewire'); -const ProtoLoader = require('../../lib/protoloader'); +const fabprotos = require('../../bundle'); const path = require('path'); const Logger = require('../../lib/logger'); +const Stub = require('../../lib/stub'); const chaincodePath = '../../lib/chaincode.js'; const StartCommand = require('../../lib/cmds/startCommand.js'); -const _serviceProto = ProtoLoader.load({ - root: path.join(__dirname, '../../lib/protos'), - file: 'peer/chaincode_shim.proto' -}).protos; - describe('Chaincode', () => { let Chaincode; describe('Chaincode \'spi\' interface', () => { @@ -105,7 +101,7 @@ describe('Chaincode', () => { const args = chat.firstCall.args; expect(args.length).to.deep.equal(1); expect(typeof args[0]).to.deep.equal('object'); - expect(args[0].type).to.deep.equal(_serviceProto.ChaincodeMessage.Type.REGISTER); + expect(args[0].type).to.deep.equal(fabprotos.protos.ChaincodeMessage.Type.REGISTER); chat.restore(); getArgsStub.restore(); @@ -218,7 +214,7 @@ describe('Chaincode', () => { const args = chat.firstCall.args; expect(args.length).to.deep.equal(1); expect(typeof args[0]).to.deep.equal('object'); - expect(args[0].type).to.deep.equal(_serviceProto.ChaincodeMessage.Type.REGISTER); + expect(args[0].type).to.deep.equal(fabprotos.protos.ChaincodeMessage.Type.REGISTER); chat.restore(); }); @@ -316,51 +312,25 @@ describe('Chaincode', () => { }); describe('response', () => { - let respProto; - let ChaincodeStub; - let mockResponse; - let saveClass; - - beforeEach(() => { - Chaincode = rewire(chaincodePath); - - respProto = Chaincode.__get__('_responseProto'); - ChaincodeStub = Chaincode.__get__('ChaincodeStub'); - mockResponse = sinon.createStubInstance(respProto.Response); - saveClass = respProto.Response; - - class MockResponse { - constructor() { - return mockResponse; - } - } - - respProto.Response = MockResponse; - }); - - after(() => { - respProto.Response = saveClass; - }); - it ('should let the code response an error', () => { const result = Chaincode.error('error msg'); expect(result.message).to.deep.equal('error msg'); - expect(result.status).to.deep.equal(ChaincodeStub.RESPONSE_CODE.ERROR); + expect(result.status).to.deep.equal(Stub.RESPONSE_CODE.ERROR); }); it ('should handle an empty success', () => { const result = Chaincode.success(); expect(result.payload).to.deep.equal(Buffer.from('')); - expect(result.status).to.deep.equal(ChaincodeStub.RESPONSE_CODE.OK); + expect(result.status).to.deep.equal(Stub.RESPONSE_CODE.OK); }); it ('should handle a success with message', () => { const result = Chaincode.success('msg'); expect(result.payload).to.deep.equal('msg'); - expect(result.status).to.deep.equal(ChaincodeStub.RESPONSE_CODE.OK); + expect(result.status).to.deep.equal(Stub.RESPONSE_CODE.OK); }); }); diff --git a/fabric-shim/test/unit/client-identity.js b/fabric-shim/test/unit/client-identity.js index a7e116ad..588e2d0a 100644 --- a/fabric-shim/test/unit/client-identity.js +++ b/fabric-shim/test/unit/client-identity.js @@ -169,16 +169,8 @@ function mockStub(cert) { return { getCreator: function() { return { - getMspid: function() { - return 'dummyId'; - }, - getIdBytes: function() { - const buf = Buffer.from(cert); - buf.toBuffer = function() { - return this; - }; - return buf; - } + mspid: 'dummyId', + idBytes: Buffer.from(cert) }; }, getTxID: function() { diff --git a/fabric-shim/test/unit/contract-spi/chaincodefromcontract.js b/fabric-shim/test/unit/contract-spi/chaincodefromcontract.js index b42d65c4..7f3160bf 100644 --- a/fabric-shim/test/unit/contract-spi/chaincodefromcontract.js +++ b/fabric-shim/test/unit/contract-spi/chaincodefromcontract.js @@ -453,11 +453,7 @@ describe('chaincodefromcontract', () => { }); it('should pass the logging object to contracts', async () => { - const idBytes = { - toBuffer: () => { - return new Buffer(certWithoutAttrs); - } - }; + const idBytes = Buffer.from(certWithoutAttrs); const tempClass = class extends Contract { constructor() { super('logging'); @@ -495,8 +491,8 @@ describe('chaincodefromcontract', () => { sandbox.stub(ChaincodeFromContract.prototype, '_compileSchemas'); const mockSigningId = { - getMspid: sinon.stub(), - getIdBytes: sinon.stub().returns(idBytes) + mspid: 'Org1MSP', + idBytes }; const cc = new ChaincodeFromContract([tempClass], defaultSerialization); const mockStub = {getBufferArgs: sandbox.stub().returns(['logging:alpha']), @@ -621,11 +617,7 @@ describe('chaincodefromcontract', () => { it ('should handle valid contract name, but missing function', async () => { - const idBytes = { - toBuffer: () => { - return new Buffer(certWithoutAttrs); - } - }; + const idBytes = Buffer.from(certWithoutAttrs); const ctx = { setChaincodeStub: sandbox.stub(), @@ -660,8 +652,8 @@ describe('chaincodefromcontract', () => { sinon.assert.calledOnce(_checkSuppliedStub); const mockSigningId = { - getMspid: sinon.stub(), - getIdBytes: sinon.stub().returns(idBytes) + mspid: 'Org1MSP', + idBytes }; const mockStub = { @@ -683,11 +675,7 @@ describe('chaincodefromcontract', () => { }); it('should handle valid contract name, but missing function and throws error', async () => { - const idBytes = { - toBuffer: () => { - return new Buffer(certWithoutAttrs); - } - }; + const idBytes = Buffer.from(certWithoutAttrs); const systemContract = new SystemContract(); @@ -705,8 +693,8 @@ describe('chaincodefromcontract', () => { sinon.assert.calledOnce(_checkSuppliedStub); const mockSigningId = { - getMspid: sinon.stub(), - getIdBytes: sinon.stub().returns(idBytes) + mspid: 'Org1MSP', + idBytes }; const ctx = { @@ -747,11 +735,7 @@ describe('chaincodefromcontract', () => { it('should handle valid contract name, with valid function', async () => { - const idBytes = { - toBuffer: () => { - return new Buffer(certWithoutAttrs); - } - }; + const idBytes = Buffer.from(certWithoutAttrs); const systemContract = new SystemContract(); @@ -769,8 +753,8 @@ describe('chaincodefromcontract', () => { sinon.assert.calledOnce(_checkSuppliedStub); const mockSigningId = { - getMspid: sinon.stub(), - getIdBytes: sinon.stub().returns(idBytes) + mspid: 'Org1MSP', + idBytes }; const ctx = { @@ -821,11 +805,7 @@ describe('chaincodefromcontract', () => { it('should handle functions with returned values schema', async () => { - const idBytes = { - toBuffer: () => { - return new Buffer(certWithoutAttrs); - } - }; + const idBytes = Buffer.from(certWithoutAttrs); const systemContract = new SystemContract(); sandbox.stub(ChaincodeFromContract.prototype, '_resolveContractImplementations') .returns({ @@ -841,8 +821,8 @@ describe('chaincodefromcontract', () => { sinon.assert.calledOnce(_checkSuppliedStub); const mockSigningId = { - getMspid: sinon.stub(), - getIdBytes: sinon.stub().returns(idBytes) + mspid: 'Org1MSP', + idBytes }; const ctx = { diff --git a/fabric-shim/test/unit/handler.js b/fabric-shim/test/unit/handler.js index 157fc980..09bf0530 100644 --- a/fabric-shim/test/unit/handler.js +++ b/fabric-shim/test/unit/handler.js @@ -20,6 +20,7 @@ const QMsg = Handler.__get__('QMsg'); const StateQueryIterator = require('../../../fabric-shim/lib/iterators.js').StateQueryIterator; const HistoryQueryIterator = require('../../../fabric-shim/lib/iterators.js').HistoryQueryIterator; +const fabprotos = require('../../bundle'); const grpc = require('grpc'); const sandbox = sinon.createSandbox(); @@ -839,15 +840,9 @@ describe('Handler', () => { let expectedMsg; before(() => { - const serviceProto = Handler.__get__('_serviceProto'); - - const payload = new serviceProto.GetState(); - payload.setKey(key); - payload.setCollection(collection); - expectedMsg = { - type: serviceProto.ChaincodeMessage.Type.GET_STATE, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.GET_STATE, + payload: fabprotos.protos.GetState.encode({key, collection}).finish(), channel_id: 'theChannelID', txid: 'theTxID' }; @@ -891,16 +886,9 @@ describe('Handler', () => { let expectedMsg; before(() => { - const serviceProto = Handler.__get__('_serviceProto'); - - const payload = new serviceProto.PutState(); - payload.setKey(key); - payload.setValue(value); - payload.setCollection(collection); - expectedMsg = { - type: serviceProto.ChaincodeMessage.Type.PUT_STATE, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.PUT_STATE, + payload: fabprotos.protos.PutState.encode({key, value, collection}).finish(), channel_id: 'theChannelID', txid: 'theTxID' }; @@ -943,15 +931,9 @@ describe('Handler', () => { let expectedMsg; before(() => { - const serviceProto = Handler.__get__('_serviceProto'); - - const payload = new serviceProto.DelState(); - payload.setKey(key); - payload.setCollection(collection); - expectedMsg = { - type: serviceProto.ChaincodeMessage.Type.DEL_STATE, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.DEL_STATE, + payload: fabprotos.protos.DelState.encode({key, collection}).finish(), channel_id: 'theChannelID', txid: 'theTxID' }; @@ -995,20 +977,16 @@ describe('Handler', () => { const ep = Buffer.from('theEP'); before(() => { - const serviceProto = Handler.__get__('_serviceProto'); - - const stateMetadata = new serviceProto.StateMetadata(); - stateMetadata.setMetakey(metadataKey); - stateMetadata.setValue(ep); - - const payload = new serviceProto.PutStateMetadata(); - payload.setKey(key); - payload.setCollection(collection); - payload.setMetadata(stateMetadata); - expectedMsg = { - type: serviceProto.ChaincodeMessage.Type.PUT_STATE_METADATA, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.PUT_STATE_METADATA, + payload: fabprotos.protos.PutStateMetadata.encode({ + key, + collection, + metadata: { + metakey: metadataKey, + value: ep + } + }).finish(), channel_id: 'theChannelID', txid: 'theTxID' }; @@ -1050,15 +1028,9 @@ describe('Handler', () => { let expectedMsg; before(() => { - const serviceProto = Handler.__get__('_serviceProto'); - - const payload = new serviceProto.GetState(); - payload.setKey(key); - payload.setCollection(collection); - expectedMsg = { - type: serviceProto.ChaincodeMessage.Type.GET_PRIVATE_DATA_HASH, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.GET_PRIVATE_DATA_HASH, + payload: fabprotos.protos.GetState.encode({key, collection}).finish(), channel_id: 'theChannelID', txid: 'theTxID' }; @@ -1100,15 +1072,9 @@ describe('Handler', () => { let expectedMsg; before(() => { - const serviceProto = Handler.__get__('_serviceProto'); - - const payload = new serviceProto.GetStateMetadata(); - payload.setKey(key); - payload.setCollection(collection); - expectedMsg = { - type: serviceProto.ChaincodeMessage.Type.GET_STATE_METADATA, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.GET_STATE_METADATA, + payload: fabprotos.protos.GetStateMetadata.encode({key, collection}).finish(), channel_id: 'theChannelID', txid: 'theTxID' }; @@ -1151,16 +1117,9 @@ describe('Handler', () => { let expectedMsg; before(() => { - const serviceProto = Handler.__get__('_serviceProto'); - - const payload = new serviceProto.GetStateByRange(); - payload.setStartKey(startKey); - payload.setEndKey(endKey); - payload.setCollection(collection); - expectedMsg = { - type: serviceProto.ChaincodeMessage.Type.GET_STATE_BY_RANGE, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.GET_STATE_BY_RANGE, + payload: fabprotos.protos.GetStateByRange.encode({startKey, endKey, collection}).finish(), channel_id: 'theChannelID', txid: 'theTxID' }; @@ -1202,17 +1161,9 @@ describe('Handler', () => { const result = await handler.handleGetStateByRange(collection, startKey, endKey, 'theChannelID', 'theTxID', metadata); - const serviceProto = Handler.__get__('_serviceProto'); - - const payload = new serviceProto.GetStateByRange(); - payload.setStartKey(startKey); - payload.setEndKey(endKey); - payload.setCollection(collection); - payload.setMetadata(metadata); - expectedMsg = { - type: serviceProto.ChaincodeMessage.Type.GET_STATE_BY_RANGE, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.GET_STATE_BY_RANGE, + payload: fabprotos.protos.GetStateByRange.encode({startKey, endKey, collection, metadata}).finish(), channel_id: 'theChannelID', txid: 'theTxID' }; @@ -1229,14 +1180,9 @@ describe('Handler', () => { let expectedMsg; before(() => { - const serviceProto = Handler.__get__('_serviceProto'); - - const payload = new serviceProto.QueryStateNext(); - payload.setId(id); - expectedMsg = { - type: serviceProto.ChaincodeMessage.Type.QUERY_STATE_NEXT, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.QUERY_STATE_NEXT, + payload: fabprotos.protos.QueryStateNext.encode({id}).finish(), channel_id: 'theChannelID', txid: 'theTxID' }; @@ -1277,14 +1223,9 @@ describe('Handler', () => { let expectedMsg; before(() => { - const serviceProto = Handler.__get__('_serviceProto'); - - const payload = new serviceProto.QueryStateClose(); - payload.setId(id); - expectedMsg = { - type: serviceProto.ChaincodeMessage.Type.QUERY_STATE_CLOSE, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.QUERY_STATE_CLOSE, + payload: fabprotos.protos.QueryStateNext.encode({id}).finish(), channel_id: 'theChannelID', txid: 'theTxID' }; @@ -1325,17 +1266,10 @@ describe('Handler', () => { const query = 'some query'; let expectedMsg; - let serviceProto; before(() => { - serviceProto = Handler.__get__('_serviceProto'); - - const payload = new serviceProto.GetQueryResult(); - payload.setQuery(query); - payload.setCollection(collection); - expectedMsg = { - type: serviceProto.ChaincodeMessage.Type.GET_QUERY_RESULT, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.GET_QUERY_RESULT, + payload: fabprotos.protos.GetQueryResult.encode({query, collection}).finish(), channel_id: 'theChannelID', txid: 'theTxID' }; @@ -1376,14 +1310,10 @@ describe('Handler', () => { const metadata = Buffer.from('some metadata'); const result = handler.handleGetQueryResult(collection, query, metadata, 'theChannelID', 'theTxID'); - const payload = new serviceProto.GetQueryResult(); - payload.setQuery(query); - payload.setCollection(collection); - payload.setMetadata(metadata); expectedMsg = { - type: serviceProto.ChaincodeMessage.Type.GET_QUERY_RESULT, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.GET_QUERY_RESULT, + payload: fabprotos.protos.GetQueryResult.encode({query, collection, metadata}).finish(), channel_id: 'theChannelID', txid: 'theTxID' }; @@ -1400,14 +1330,9 @@ describe('Handler', () => { let expectedMsg; before(() => { - const serviceProto = Handler.__get__('_serviceProto'); - - const payload = new serviceProto.GetHistoryForKey(); - payload.setKey(key); - expectedMsg = { - type: serviceProto.ChaincodeMessage.Type.GET_HISTORY_FOR_KEY, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.GET_HISTORY_FOR_KEY, + payload: fabprotos.protos.GetHistoryForKey.encode({key}).finish(), channel_id: 'theChannelID', txid: 'theTxID' }; @@ -1447,27 +1372,20 @@ describe('Handler', () => { const chaincodeName = 'myChaincode'; const args = ['duck', 'duck', 'goose']; - const serviceProto = Handler.__get__('_serviceProto'); - let expectedMsg; before(() => { - const chaincodeProto = Handler.__get__('_chaincodeProto'); - - const payload = new chaincodeProto.ChaincodeSpec(); - const chaincodeId = new chaincodeProto.ChaincodeID(); - const chaincodeInput = new chaincodeProto.ChaincodeInput(); - chaincodeId.setName(chaincodeName); - const inputArgs = []; - args.forEach((arg) => { - inputArgs.push(Buffer.from(arg, 'utf8')); - }); - chaincodeInput.setArgs(inputArgs); - payload.setChaincodeId(chaincodeId); - payload.setInput(chaincodeInput); + const argsAsBuffers = args.map((arg) => Buffer.from(arg, 'utf8')); expectedMsg = { - type: serviceProto.ChaincodeMessage.Type.INVOKE_CHAINCODE, - payload: payload.toBuffer(), + type: fabprotos.protos.ChaincodeMessage.Type.INVOKE_CHAINCODE, + payload: fabprotos.protos.ChaincodeSpec.encode({ + chaincodeId: { + name: chaincodeName + }, + input: { + args: argsAsBuffers + } + }).finish(), channel_id: 'theChannelID', txid: 'theTxID' }; @@ -1479,10 +1397,9 @@ describe('Handler', () => { }); it ('should return decoded response when chaincode message type COMPLETED', async () => { - const responseProto = Handler.__get__('_responseProto'); const handler = new Handler(mockChaincodeImpl, mockPeerAddress.unsecure); - const _askPeerAndListenStub = sandbox.stub(handler, '_askPeerAndListen').resolves({type: serviceProto.ChaincodeMessage.Type.COMPLETED, payload: 'some payload'}); - const decodeStub = sandbox.stub(responseProto.Response, 'decode').returns('some response'); + const _askPeerAndListenStub = sandbox.stub(handler, '_askPeerAndListen').resolves({type: fabprotos.protos.ChaincodeMessage.Type.COMPLETED, payload: 'some payload'}); + const decodeStub = sandbox.stub(fabprotos.protos.Response, 'decode').returns('some response'); const result = await handler.handleInvokeChaincode(chaincodeName, args, 'theChannelID', 'theTxID'); @@ -1495,10 +1412,9 @@ describe('Handler', () => { }); it ('should throw an error when _askPeerAndListen resolves with an error', async () => { - const responseProto = Handler.__get__('_responseProto'); const handler = new Handler(mockChaincodeImpl, mockPeerAddress.unsecure); - const _askPeerAndListenStub = sandbox.stub(handler, '_askPeerAndListen').resolves({type: serviceProto.ChaincodeMessage.Type.ERROR, payload: 'some payload'}); - const decodeStub = sandbox.stub(responseProto.Response, 'decode').returns('some response'); + const _askPeerAndListenStub = sandbox.stub(handler, '_askPeerAndListen').resolves({type: fabprotos.protos.ChaincodeMessage.Type.ERROR, payload: 'some payload'}); + const decodeStub = sandbox.stub(fabprotos.protos.Response, 'decode').returns('some response'); const result = handler.handleInvokeChaincode(chaincodeName, args, 'theChannelID', 'theTxID'); @@ -1510,10 +1426,9 @@ describe('Handler', () => { }); it ('should reject when _askPeerAndListen resolves', async () => { - const responseProto = Handler.__get__('_responseProto'); const handler = new Handler(mockChaincodeImpl, mockPeerAddress.unsecure); const _askPeerAndListenStub = sandbox.stub(handler, '_askPeerAndListen').rejects(); - const decodeStub = sandbox.stub(responseProto.Response, 'decode').returns('some response'); + const decodeStub = sandbox.stub(fabprotos.protos.Response, 'decode').returns('some response'); const result = handler.handleInvokeChaincode(chaincodeName, args, 'theChannelID', 'theTxID'); @@ -1525,10 +1440,9 @@ describe('Handler', () => { }); it ('should return nothing chaincode message type not COMPLETED or ERROR', async () => { - const responseProto = Handler.__get__('_responseProto'); const handler = new Handler(mockChaincodeImpl, mockPeerAddress.unsecure); - const _askPeerAndListenStub = sandbox.stub(handler, '_askPeerAndListen').resolves({type: serviceProto.ChaincodeMessage.Type.SOMETHING_ELSE, payload: 'some payload'}); - const decodeStub = sandbox.stub(responseProto.Response, 'decode').returns('some response'); + const _askPeerAndListenStub = sandbox.stub(handler, '_askPeerAndListen').resolves({type: fabprotos.protos.ChaincodeMessage.Type.SOMETHING_ELSE, payload: 'some payload'}); + const decodeStub = sandbox.stub(fabprotos.protos.Response, 'decode').returns('some response'); const result = await handler.handleInvokeChaincode(chaincodeName, args, 'theChannelID', 'theTxID'); @@ -1573,8 +1487,6 @@ describe('Handler', () => { describe('handleMessage', () => { let handleMessage; - let chaincodeProto; - let serviceProto; let decodeStub; @@ -1599,12 +1511,10 @@ describe('Handler', () => { beforeEach(() => { handleMessage = Handler.__get__('handleMessage'); - chaincodeProto = Handler.__get__('_chaincodeProto'); - serviceProto = Handler.__get__('_serviceProto'); mockHandler._stream = {write: sinon.stub()}; - decodeStub = sandbox.stub(chaincodeProto.ChaincodeInput, 'decode').returns('some message'); + decodeStub = sandbox.stub(fabprotos.protos.ChaincodeInput, 'decode').returns('some message'); const createStubStub = sandbox.stub().returns(mockStub); Handler.__set__('createStub', createStubStub); @@ -1620,7 +1530,7 @@ describe('Handler', () => { beforeEach(() => { expectedResponse = { - type: serviceProto.ChaincodeMessage.Type.ERROR, + type: fabprotos.protos.ChaincodeMessage.Type.ERROR, payload: Buffer.from('shim message'), channel_id: msg.channel_id, txid: msg.txid @@ -1629,7 +1539,7 @@ describe('Handler', () => { it ('should handle an error decoding the payload', async () => { decodeStub.restore(); - decodeStub = sandbox.stub(chaincodeProto.ChaincodeInput, 'decode').throws('some error'); + decodeStub = sandbox.stub(fabprotos.protos.ChaincodeInput, 'decode').throws('some error'); expectedResponse.payload = msg.payload; @@ -1724,8 +1634,8 @@ describe('Handler', () => { beforeEach(() => { expectedResponse = { - type: serviceProto.ChaincodeMessage.Type.COMPLETED, - payload: 'a buffered payload', + type: fabprotos.protos.ChaincodeMessage.Type.COMPLETED, + payload: fabprotos.protos.Response.encode({status: Stub.RESPONSE_CODE.OK}).finish(), channel_id: msg.channel_id, txid: msg.txid, chaincode_event: mockStub.chaincodeEvent @@ -1733,9 +1643,7 @@ describe('Handler', () => { }); it ('should write a COMPLETE message when successful init', async () => { - mockHandler.chaincode.Init = sandbox.stub().resolves({status: Stub.RESPONSE_CODE.OK, toBuffer: () => { - return 'a buffered payload'; - }}); + mockHandler.chaincode.Init = sandbox.stub().resolves({status: Stub.RESPONSE_CODE.OK}); await handleMessage(msg, mockHandler, 'init'); @@ -1747,9 +1655,7 @@ describe('Handler', () => { }); it ('should write a COMPLETE message when successful invoke', async () => { - mockHandler.chaincode.Invoke = sandbox.stub().resolves({status: Stub.RESPONSE_CODE.OK, toBuffer: () => { - return 'a buffered payload'; - }}); + mockHandler.chaincode.Invoke = sandbox.stub().resolves({status: Stub.RESPONSE_CODE.OK}); await handleMessage(msg, mockHandler, 'invoke'); @@ -1819,25 +1725,23 @@ describe('Handler', () => { before(() => { handleGetStateMetadata = Handler.__get__('handleGetStateMetadata'); - const serviceProto = Handler.__get__('_serviceProto'); ep = Buffer.from('someEP'); metaKey = 'theMetaKey'; - const stateMetadata = new serviceProto.StateMetadata(); - stateMetadata.setMetakey(metaKey); - stateMetadata.setValue(ep); - - payload = new serviceProto.StateMetadataResult(); - const entries = [stateMetadata]; - payload.setEntries(entries); - - payload = payload.toBuffer(); + payload = fabprotos.protos.StateMetadataResult.encode({ + entries: [ + { + metakey: metaKey, + value: ep + } + ] + }).finish(); }); it('should success', () => { const res = handleGetStateMetadata(payload); expect(res).to.haveOwnProperty(metaKey); - expect(res[metaKey].toBuffer()).to.eql(ep); + expect(res[metaKey]).to.eql(ep); }); }); @@ -1848,7 +1752,6 @@ describe('Handler', () => { let MSG_TYPE; - let serviceProto; let parseResponse; let handler; @@ -1863,16 +1766,9 @@ describe('Handler', () => { MSG_TYPE = Handler.__get__('MSG_TYPE'); - serviceProto = Handler.__get__('_serviceProto'); - serviceProto.QueryResponse = { - decode: sinon.stub().returns(qrDecodedPayload) - }; - serviceProto.ChaincodeMessage = { - decode: sinon.stub().returns(ccDecodedPayload) - }; - serviceProto.QueryResponseMetadata = { - decode: sinon.stub().returns(mdDecodedPayload) - }; + sandbox.stub(fabprotos.protos.QueryResponse, 'decode').returns(qrDecodedPayload); + sandbox.stub(fabprotos.protos.ChaincodeMessage, 'decode').returns(ccDecodedPayload); + sandbox.stub(fabprotos.protos.QueryResponseMetadata, 'decode').returns(mdDecodedPayload); parseResponse = Handler.__get__('parseResponse'); }); @@ -1968,9 +1864,7 @@ describe('Handler', () => { results: 'some results', metadata: 'some metadata', }; - serviceProto.QueryResponse = { - decode: sinon.stub().returns(pagedQrPayload) - }; + fabprotos.protos.QueryResponse.decode.returns(pagedQrPayload); Handler.__set__('StateQueryIterator', mockStateQueryIterator); const result = parseResponse(handler, res, 'GetStateByRange'); @@ -1979,9 +1873,7 @@ describe('Handler', () => { expect(mockStateQueryIterator.firstCall.args).to.deep.equal([handler, res.channel_id, res.txid, pagedQrPayload]); expect(result.metadata).to.eql(mdDecodedPayload); - serviceProto.QueryResponse = { - decode: sinon.stub().returns(qrDecodedPayload) - }; + fabprotos.protos.QueryResponse.decode.returns(qrDecodedPayload); }); it ('should return a StateQueryIterator for GetQueryResult', () => { diff --git a/fabric-shim/test/unit/iterators.js b/fabric-shim/test/unit/iterators.js index 24651f81..fa3efa15 100644 --- a/fabric-shim/test/unit/iterators.js +++ b/fabric-shim/test/unit/iterators.js @@ -15,6 +15,7 @@ const Iterator = rewire('../../../fabric-shim/lib/iterators.js'); const StateQueryIterator = Iterator.StateQueryIterator; const HistoryQueryIterator = Iterator.HistoryQueryIterator; const handler = require('../../../fabric-shim/lib/handler.js'); +const fabprotos = require('../../bundle'); const channel_id = 'theChannelId'; const txID = 'aTx'; @@ -59,9 +60,8 @@ describe('Iterator', () => { describe('_getResultFromBytes', () => { - const QRProto = Iterator.__get__('_queryresultProto'); - QRProto.KV.decode = sinon.stub().returns('decoded KV'); - QRProto.KeyModification.decode = sinon.stub().returns('decoded Keymodification'); + fabprotos.queryresult.KV.decode = sinon.stub().returns('decoded KV'); + fabprotos.queryresult.KeyModification.decode = sinon.stub().returns('decoded Keymodification'); it ('should return KV decode on resultbytes for a QUERY type', () => { const ci = new CommonIterator(mockHandler, channel_id, txID, mockResponse, 'QUERY'); diff --git a/fabric-shim/test/unit/stub.js b/fabric-shim/test/unit/stub.js index 99c285be..27405d9a 100644 --- a/fabric-shim/test/unit/stub.js +++ b/fabric-shim/test/unit/stub.js @@ -5,19 +5,12 @@ */ /* global describe it beforeEach afterEach after */ -const ByteBuffer = require('bytebuffer'); const sinon = require('sinon'); const chai = require('chai'); chai.use(require('chai-as-promised')); const expect = chai.expect; const rewire = require('rewire'); -const ProtoLoader = require('../../lib/protoloader'); -const path = require('path'); - -const _serviceProto = ProtoLoader.load({ - root: path.join(__dirname, '../../lib/protos'), - file: 'peer/chaincode_shim.proto' -}).protos; +const fabprotos = require('../../bundle'); const Stub = rewire('../../lib/stub.js'); @@ -73,15 +66,11 @@ describe('Stub', () => { const decodedSP = { proposal: { header: { - signature_header: { + signatureHeader: { nonce: Buffer.from('100'), - creator: { - toBuffer: () => { - return Buffer.from('some creator'); - } - } + creator: Buffer.from('some creator') }, - channel_header: { + channelHeader: { epoch: { high: 10, low: 1 @@ -91,7 +80,7 @@ describe('Stub', () => { } }; - expect(computeProposalBinding(decodedSP)).to.deep.equal('44206e945c5cc2b752deacc05b2d6cd58a3799fec52143c986739bab57417aaf'); + expect(computeProposalBinding(decodedSP)).to.deep.equal('ff7e9beabf035d45cb5922278f423ba92f1e85d43d54c2304038f2f2b131625b'); }); }); @@ -216,42 +205,29 @@ describe('Stub', () => { describe('ChaincodeStub', () => { const sandbox = sinon.createSandbox(); - const buf1 = ByteBuffer.fromUTF8('invoke'); - const buf2 = ByteBuffer.fromUTF8('someKey'); - const buf3 = ByteBuffer.fromUTF8('someValue'); + const buf1 = Buffer.from('invoke'); + const buf2 = Buffer.from('someKey'); + const buf3 = Buffer.from('someValue'); const decodedProposal = { - header: { - toBuffer: () => { - return Buffer.from('some header'); - } - }, - payload: { - toBuffer: () => { - return Buffer.from('some payload'); - } - } + header: Buffer.from('some header'), + payload: Buffer.from('some payload') }; const decodedCCPP = { - getTransientMap: () => { - return 'some transient map'; + TransientMap: { + key1: 'value1', + key2: 'value2' } }; const decodedHeader = { - signature_header: 'some signature header', - channel_header: 'somne channel header' + signatureHeader: 'some signature header', + channelHeader: 'somne channel header' }; const decodedSigHeader = { - getNonce: () => { - return { - toBuffer: () => { - return Buffer.from('some nonce'); - } - }; - }, + nonce: Buffer.from('some nonce'), creator: 'some creator' }; @@ -259,27 +235,22 @@ describe('Stub', () => { timestamp: 'some timestamp' }; - const _proposalProto = Stub.__get__('_proposalProto'); let _proposalProtoProposalDecodeStub; let _proposalProtoChaincodeProposalPayloadDecodeStub; - - const _commonProto = Stub.__get__('_commonProto'); let _commonProtoHeaderDecodeStub; let _commonProtoSignatureHeaderDecodeStub; let _commonProtoChannelHeaderDecodeStub; - - const _idProto = Stub.__get__('_idProto'); let _idProtoSerializedIdentityDecodeStub; beforeEach(() => { - _proposalProtoProposalDecodeStub = sandbox.stub(_proposalProto.Proposal, 'decode').returns(decodedProposal); - _proposalProtoChaincodeProposalPayloadDecodeStub = sandbox.stub(_proposalProto.ChaincodeProposalPayload, 'decode').returns(decodedCCPP); + _proposalProtoProposalDecodeStub = sandbox.stub(fabprotos.protos.Proposal, 'decode').returns(decodedProposal); + _proposalProtoChaincodeProposalPayloadDecodeStub = sandbox.stub(fabprotos.protos.ChaincodeProposalPayload, 'decode').returns(decodedCCPP); - _commonProtoHeaderDecodeStub = sandbox.stub(_commonProto.Header, 'decode').returns(decodedHeader); - _commonProtoSignatureHeaderDecodeStub = sandbox.stub(_commonProto.SignatureHeader, 'decode').returns(decodedSigHeader); - _commonProtoChannelHeaderDecodeStub = sandbox.stub(_commonProto.ChannelHeader, 'decode').returns(decodedChannelHeader); + _commonProtoHeaderDecodeStub = sandbox.stub(fabprotos.common.Header, 'decode').returns(decodedHeader); + _commonProtoSignatureHeaderDecodeStub = sandbox.stub(fabprotos.common.SignatureHeader, 'decode').returns(decodedSigHeader); + _commonProtoChannelHeaderDecodeStub = sandbox.stub(fabprotos.common.ChannelHeader, 'decode').returns(decodedChannelHeader); - _idProtoSerializedIdentityDecodeStub = sandbox.stub(_idProto.SerializedIdentity, 'decode').returns('some creator'); + _idProtoSerializedIdentityDecodeStub = sandbox.stub(fabprotos.msp.SerializedIdentity, 'decode').returns('some creator'); }); afterEach(() => { @@ -299,7 +270,7 @@ describe('Stub', () => { it ('should throw an error for an invalid proposal', () => { _proposalProtoProposalDecodeStub.restore(); - _proposalProtoProposalDecodeStub = sandbox.stub(_proposalProto.Proposal, 'decode').throws(); + _proposalProtoProposalDecodeStub = sandbox.stub(fabprotos.protos.Proposal, 'decode').throws(); expect(() => { new Stub('dummyClient', 'dummyChannelId', 'dummyTxid', { @@ -310,7 +281,7 @@ describe('Stub', () => { it ('should throw an error for a proposal with an empty header', () => { _proposalProtoProposalDecodeStub.restore(); - _proposalProtoProposalDecodeStub = sandbox.stub(_proposalProto.Proposal, 'decode').returns({}); + _proposalProtoProposalDecodeStub = sandbox.stub(fabprotos.protos.Proposal, 'decode').returns({}); expect(() => { new Stub('dummyClient', 'dummyChannelId', 'dummyTxid', { @@ -324,7 +295,7 @@ describe('Stub', () => { it ('should throw an error for a proposal with an empty payload', () => { _proposalProtoProposalDecodeStub.restore(); - _proposalProtoProposalDecodeStub = sandbox.stub(_proposalProto.Proposal, 'decode').returns({header: decodedProposal.header}); + _proposalProtoProposalDecodeStub = sandbox.stub(fabprotos.protos.Proposal, 'decode').returns({header: decodedProposal.header}); expect(() => { new Stub('dummyClient', 'dummyChannelId', 'dummyTxid', { @@ -338,7 +309,7 @@ describe('Stub', () => { it ('should throw an error for a proposal with an invalid header', () => { _commonProtoHeaderDecodeStub.restore(); - _commonProtoHeaderDecodeStub = sandbox.stub(_commonProto.Header, 'decode').throws(); + _commonProtoHeaderDecodeStub = sandbox.stub(fabprotos.common.Header, 'decode').throws(); expect(() => { new Stub('dummyClient', 'dummyChannelId', 'dummyTxid', { @@ -352,7 +323,7 @@ describe('Stub', () => { it ('should throw an error for a proposal with an invalid signature header', () => { _commonProtoSignatureHeaderDecodeStub.restore(); - _commonProtoSignatureHeaderDecodeStub = sandbox.stub(_commonProto.SignatureHeader, 'decode').throws(); + _commonProtoSignatureHeaderDecodeStub = sandbox.stub(fabprotos.common.SignatureHeader, 'decode').throws(); expect(() => { new Stub('dummyClient', 'dummyChannelId', 'dummyTxid', { @@ -366,7 +337,7 @@ describe('Stub', () => { it ('should throw an error for a proposal with an invalid creator', () => { _idProtoSerializedIdentityDecodeStub.restore(); - _idProtoSerializedIdentityDecodeStub = sandbox.stub(_idProto.SerializedIdentity, 'decode').throws(); + _idProtoSerializedIdentityDecodeStub = sandbox.stub(fabprotos.msp.SerializedIdentity, 'decode').throws(); expect(() => { new Stub('dummyClient', 'dummyChannelId', 'dummyTxid', { @@ -380,7 +351,7 @@ describe('Stub', () => { it ('should throw an error for a proposal with an invalid channelHeader', () => { _commonProtoChannelHeaderDecodeStub.restore(); - _commonProtoChannelHeaderDecodeStub = sandbox.stub(_commonProto.ChannelHeader, 'decode').throws(); + _commonProtoChannelHeaderDecodeStub = sandbox.stub(fabprotos.common.ChannelHeader, 'decode').throws(); expect(() => { new Stub('dummyClient', 'dummyChannelId', 'dummyTxid', { @@ -394,7 +365,7 @@ describe('Stub', () => { it ('should throw an error for a proposal with an invalid payload', () => { _proposalProtoChaincodeProposalPayloadDecodeStub.restore(); - sandbox.stub(_proposalProto.ChaincodeProposalPayload, 'decode').throws(); + sandbox.stub(fabprotos.protos.ChaincodeProposalPayload, 'decode').throws(); expect(() => { new Stub('dummyClient', 'dummyChannelId', 'dummyTxid', { @@ -426,7 +397,8 @@ describe('Stub', () => { expect(stub.proposal).to.deep.equal(decodedProposal); expect(stub.txTimestamp).to.deep.equal('some timestamp'); expect(stub.creator).to.deep.equal('some creator'); - expect(stub.transientMap).to.deep.equal('some transient map'); + expect(stub.transientMap.get('key1')).to.equal('value1'); + expect(stub.transientMap.get('key2')).to.equal('value2'); expect(stub.signedProposal).to.deep.equal({ signature: 'some signature', proposal: { @@ -447,11 +419,11 @@ describe('Stub', () => { expect(_commonProtoHeaderDecodeStub.calledOnce).to.be.ok; expect(_commonProtoHeaderDecodeStub.firstCall.args).to.deep.equal([decodedProposal.header]); expect(_commonProtoSignatureHeaderDecodeStub.calledOnce).to.be.ok; - expect(_commonProtoSignatureHeaderDecodeStub.firstCall.args).to.deep.equal([decodedHeader.signature_header]); + expect(_commonProtoSignatureHeaderDecodeStub.firstCall.args).to.deep.equal([decodedHeader.signatureHeader]); expect(_idProtoSerializedIdentityDecodeStub.calledOnce).to.be.ok; expect(_idProtoSerializedIdentityDecodeStub.firstCall.args).to.deep.equal([decodedSigHeader.creator]); expect(_commonProtoChannelHeaderDecodeStub.calledOnce).to.be.ok; - expect(_commonProtoChannelHeaderDecodeStub.firstCall.args).to.deep.equal([decodedHeader.channel_header]); + expect(_commonProtoChannelHeaderDecodeStub.firstCall.args).to.deep.equal([decodedHeader.channelHeader]); expect(_proposalProtoChaincodeProposalPayloadDecodeStub.calledOnce).to.be.ok; expect(_proposalProtoChaincodeProposalPayloadDecodeStub.firstCall.args).to.deep.equal([decodedProposal.payload]); @@ -484,7 +456,7 @@ describe('Stub', () => { args: [buf1, buf2, buf3] }); - expect(stub.getBufferArgs()).to.deep.equal([buf1.buffer, buf2.buffer, buf3.buffer]); + expect(stub.getBufferArgs()).to.deep.equal([buf1, buf2, buf3]); }); }); @@ -789,10 +761,11 @@ describe('Stub', () => { expect(result).to.deep.equal('some state'); expect(handleGetStateByRangeStub.calledOnce).to.be.ok; - const metadata = new _serviceProto.QueryResponseMetadata(); - metadata.setBookmark(''); - metadata.setFetchedRecordsCount(3); - expect(handleGetStateByRangeStub.firstCall.args).to.deep.equal(['', EMPTY_KEY_SUBSTITUTE, 'end key', 'dummyChannelId', 'dummyTxid', metadata.toBuffer()]); + const metadataBuffer = fabprotos.protos.QueryResponseMetadata.encode({ + bookmark: '', + fetchedRecordsCount: 3 + }).finish(); + expect(handleGetStateByRangeStub.firstCall.args).to.deep.equal(['', EMPTY_KEY_SUBSTITUTE, 'end key', 'dummyChannelId', 'dummyTxid', metadataBuffer]); }); it('should have default bookmark eqls an empty string', async () => { @@ -808,10 +781,11 @@ describe('Stub', () => { expect(result).to.deep.equal('some state'); expect(handleGetStateByRangeStub.calledOnce).to.be.ok; - const metadata = new _serviceProto.QueryResponseMetadata(); - metadata.setFetchedRecordsCount(3); - metadata.setBookmark(''); - expect(handleGetStateByRangeStub.firstCall.args).to.deep.equal(['', 'start key', 'end key', 'dummyChannelId', 'dummyTxid', metadata.toBuffer()]); + const metadataBuffer = fabprotos.protos.QueryResponseMetadata.encode({ + bookmark: '', + fetchedRecordsCount: 3 + }).finish(); + expect(handleGetStateByRangeStub.firstCall.args).to.deep.equal(['', 'start key', 'end key', 'dummyChannelId', 'dummyTxid', metadataBuffer]); }); it('should have default bookmark eqls an empty string', async () => { @@ -827,10 +801,11 @@ describe('Stub', () => { expect(result).to.deep.equal('some state'); expect(handleGetStateByRangeStub.calledOnce).to.be.ok; - const metadata = new _serviceProto.QueryResponseMetadata(); - metadata.setFetchedRecordsCount(3); - metadata.setBookmark('a bookmark'); - expect(handleGetStateByRangeStub.firstCall.args).to.deep.equal(['', 'start key', 'end key', 'dummyChannelId', 'dummyTxid', metadata.toBuffer()]); + const metadataBuffer = fabprotos.protos.QueryResponseMetadata.encode({ + bookmark: 'a bookmark', + fetchedRecordsCount: 3 + }).finish(); + expect(handleGetStateByRangeStub.firstCall.args).to.deep.equal(['', 'start key', 'end key', 'dummyChannelId', 'dummyTxid', metadataBuffer]); }); }); @@ -867,7 +842,7 @@ describe('Stub', () => { expect(result).to.deep.equal('some query result'); expect(handleGetQueryResultStub.calledOnce).to.be.ok; const metadata = handleGetQueryResultStub.firstCall.args[2]; - const decoded = _serviceProto.QueryMetadata.decode(metadata); + const decoded = fabprotos.protos.QueryMetadata.decode(metadata); expect(decoded.pageSize).to.equal(3); expect(decoded.bookmark).to.equal(''); }); @@ -886,7 +861,7 @@ describe('Stub', () => { expect(result).to.deep.equal('some query result'); expect(handleGetQueryResultStub.calledOnce).to.be.ok; const metadata = handleGetQueryResultStub.firstCall.args[2]; - const decoded = _serviceProto.QueryMetadata.decode(metadata); + const decoded = fabprotos.protos.QueryMetadata.decode(metadata); expect(decoded.pageSize).to.equal(3); expect(decoded.bookmark).to.equal('a bookmark'); }); @@ -963,31 +938,9 @@ describe('Stub', () => { }); it ('should set an event', () => { - const saveEventProto = Stub.__get__('_eventProto'); - - const setEventNameSpy = sinon.spy(); - const setPayloadSpy = sinon.spy(); - - function CustomEvent () { - this.setEventName = setEventNameSpy; - this.setPayload = setPayloadSpy; - } - - const eventProtoStub = { - ChaincodeEvent: CustomEvent - }; - - Stub.__set__('_eventProto', eventProtoStub); - - stub.setEvent('some name', 'some payload'); - - expect(stub.chaincodeEvent).to.deep.equal(new CustomEvent()); - expect(setEventNameSpy.calledOnce).to.be.ok; - expect(setEventNameSpy.firstCall.args).to.deep.equal(['some name']); - expect(setPayloadSpy.calledOnce).to.be.ok; - expect(setPayloadSpy.firstCall.args).to.deep.equal(['some payload']); - - Stub.__set__('_eventProto', saveEventProto); + stub.setEvent('some name', Buffer.from('some payload')); + expect(stub.chaincodeEvent.eventName).to.equal('some name'); + expect(stub.chaincodeEvent.payload).to.deep.equal(Buffer.from('some payload')); }); }); @@ -1111,7 +1064,7 @@ describe('Stub', () => { expect(createCompositeKeyStub.firstCall.args).to.deep.equal(['some type', ['attr1', 'attr2']]); expect(handleGetStateByRangeStub.calledOnce).to.be.ok; const metadata = handleGetStateByRangeStub.firstCall.args[5]; - const decoded = _serviceProto.QueryMetadata.decode(metadata); + const decoded = fabprotos.protos.QueryMetadata.decode(metadata); expect(decoded.pageSize).to.equal(3); expect(decoded.bookmark).to.equal(''); }); @@ -1130,7 +1083,7 @@ describe('Stub', () => { expect(createCompositeKeyStub.firstCall.args).to.deep.equal(['some type', ['attr1', 'attr2']]); expect(handleGetStateByRangeStub.calledOnce).to.be.ok; const metadata = handleGetStateByRangeStub.firstCall.args[5]; - const decoded = _serviceProto.QueryMetadata.decode(metadata); + const decoded = fabprotos.protos.QueryMetadata.decode(metadata); expect(decoded.pageSize).to.equal(23); expect(decoded.bookmark).to.equal('a bookmark'); }); diff --git a/fabric-shim/test/unit/utils/statebased.js b/fabric-shim/test/unit/utils/statebased.js index bb0d630e..46142876 100644 --- a/fabric-shim/test/unit/utils/statebased.js +++ b/fabric-shim/test/unit/utils/statebased.js @@ -84,26 +84,11 @@ describe('KeyEndorsementPolicy', () => { expect(policy).haveOwnProperty('version').eqls(0); expect(policy).haveOwnProperty('identities').to.be.an('array'); expect(policy.identities.length).to.eql(3); - expect(policy.rule.toRaw()).to.deep.eqls({ - n_out_of: { - n: 3, - rules: [{ - n_out_of: null, - signed_by: 0, - Type: 'signed_by' - }, { - n_out_of: null, - signed_by: 1, - Type: 'signed_by' - }, { - n_out_of: null, - signed_by: 2, - Type: 'signed_by' - }] - }, - signed_by: 0, - Type: 'n_out_of' - }); + expect(policy.rule.nOutOf.n).to.eql(3); + expect(policy.rule.nOutOf.rules.length).to.eql(3); + expect(policy.rule.nOutOf.rules[0].signedBy).to.eql(0); + expect(policy.rule.nOutOf.rules[1].signedBy).to.eql(1); + expect(policy.rule.nOutOf.rules[2].signedBy).to.eql(2); }); }); diff --git a/fabric-shim/types/index.d.ts b/fabric-shim/types/index.d.ts index 946b7e3f..4ed112ff 100644 --- a/fabric-shim/types/index.d.ts +++ b/fabric-shim/types/index.d.ts @@ -44,9 +44,7 @@ declare module 'fabric-shim' { interface SerializedIdentity { mspid: string; - id_bytes: Buffer; - getMspid(): string; - getIdBytes(): Buffer; + idBytes: Buffer; } interface QueryResponseMetadata { diff --git a/test/fv/crud.js b/test/fv/crud.js index f2299a6c..7e1c42e8 100755 --- a/test/fv/crud.js +++ b/test/fv/crud.js @@ -95,7 +95,7 @@ describe('Chaincode CRUD', () => { const payload = JSON.parse(await utils.query(suite, 'org.mynamespace.crud:getQueryResultWithPagination', [])); expect(payload.results1.length).to.equal(2, 'Should return 2 keys'); expect(payload.results1).to.deep.equal(['jsonkey0', 'jsonkey1']); - expect(payload.metadata1.fetched_records_count).to.equal(2); + expect(payload.metadata1.fetchedRecordsCount).to.equal(2); expect(payload.metadata1.bookmark).to.exist; }); @@ -105,7 +105,7 @@ describe('Chaincode CRUD', () => { const payload = JSON.parse(await utils.query(suite, 'org.mynamespace.crud:getQueryResultWithPaginationUsingAsyncIterator', [])); expect(payload.results1.length).to.equal(2, 'Should return 2 keys'); expect(payload.results1).to.deep.equal(['jsonkey0', 'jsonkey1']); - expect(payload.metadata1.fetched_records_count).to.equal(2); + expect(payload.metadata1.fetchedRecordsCount).to.equal(2); expect(payload.metadata1.bookmark).to.exist; }); @@ -116,7 +116,7 @@ describe('Chaincode CRUD', () => { const payload = JSON.parse(await utils.query(suite, 'org.mynamespace.crud:getQueryResultWithPagination', [])); expect(payload.results2.length).to.equal(1); expect(payload.results2).to.deep.equal(['jsonkey2']); - expect(payload.metadata2.fetched_records_count).to.equal(1); + expect(payload.metadata2.fetchedRecordsCount).to.equal(1); }); it('should get a query result with pagination with a set bookmark using the new iterator style', async function () { @@ -125,7 +125,7 @@ describe('Chaincode CRUD', () => { const payload = JSON.parse(await utils.query(suite, 'org.mynamespace.crud:getQueryResultWithPaginationUsingAsyncIterator', [])); expect(payload.results2.length).to.equal(1); expect(payload.results2).to.deep.equal(['jsonkey2']); - expect(payload.metadata2.fetched_records_count).to.equal(1); + expect(payload.metadata2.fetchedRecordsCount).to.equal(1); });