From 2b9767975bbfc134268033a665441a50361d3854 Mon Sep 17 00:00:00 2001 From: Peter Somogyvari Date: Thu, 22 Jul 2021 15:30:44 -0700 Subject: [PATCH] feat(connector-fabric): endorsing peers request arg #1122 Makes it possible to set the endorsing peers on a transaction when submitted through the Fabric connector. For example these values can be passed in to the new parameter and it will set the endorsers up accordingly prior to submitting the transaction to the ledger: - org1.example.com - Org1MSP - org2.example.com - Org2MSP (You only need either the org domain or the msp ID, no need to specify both of them for it to work). For a working example, see this test case: packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/ integration/fabric-v2-2-x/run-transaction-endpoint-v1.test.ts Depends on #1123 Depends on #1130 Fixes #1122 Signed-off-by: Peter Somogyvari --- .cspell.json | 1 + .../src/main/json/openapi.json | 10 ++++++ .../generated/openapi/typescript-axios/api.ts | 6 ++++ .../plugin-ledger-connector-fabric.ts | 34 ++++++++++++++++++- .../run-transaction-endpoint-v1.test.ts | 23 +++++++++++++ 5 files changed, 73 insertions(+), 1 deletion(-) diff --git a/.cspell.json b/.cspell.json index 89c3df83ea..3b12a39296 100644 --- a/.cspell.json +++ b/.cspell.json @@ -29,6 +29,7 @@ "escc", "execa", "faio", + "fidm", "fsouza", "GETHKEYCHAINPASSWORD", "ghcr", diff --git a/packages/cactus-plugin-ledger-connector-fabric/src/main/json/openapi.json b/packages/cactus-plugin-ledger-connector-fabric/src/main/json/openapi.json index 3b058acea2..793826836a 100644 --- a/packages/cactus-plugin-ledger-connector-fabric/src/main/json/openapi.json +++ b/packages/cactus-plugin-ledger-connector-fabric/src/main/json/openapi.json @@ -331,6 +331,16 @@ "params" ], "properties": { + "endorsingPeers": { + "description": "An array of MSP IDs to set as the list of endorsing peers for the transaction.", + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "maxLength": 4096, + "nullable": false + } + }, "transientData": { "type": "object", "nullable": true diff --git a/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/generated/openapi/typescript-axios/api.ts b/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/generated/openapi/typescript-axios/api.ts index 7572dcd8c7..a29c68fcf2 100644 --- a/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/generated/openapi/typescript-axios/api.ts +++ b/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/generated/openapi/typescript-axios/api.ts @@ -680,6 +680,12 @@ export interface InlineResponse501 { * @interface RunTransactionRequest */ export interface RunTransactionRequest { + /** + * An array of MSP IDs to set as the list of endorsing peers for the transaction. + * @type {Array} + * @memberof RunTransactionRequest + */ + endorsingPeers?: Array; /** * * @type {object} diff --git a/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/plugin-ledger-connector-fabric.ts b/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/plugin-ledger-connector-fabric.ts index 8a1b4a64c4..85cae56513 100644 --- a/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/plugin-ledger-connector-fabric.ts +++ b/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/plugin-ledger-connector-fabric.ts @@ -3,6 +3,7 @@ import path from "path"; import { Server } from "http"; import { Server as SecureServer } from "https"; +import { Certificate } from "@fidm/x509"; import { Express } from "express"; import "multer"; import temp from "temp"; @@ -88,6 +89,7 @@ import { import { sourceLangToRuntimeLang } from "./peer/source-lang-to-runtime-lang"; import FabricCAServices from "fabric-ca-client"; import { createGateway } from "./common/create-gateway"; +import { Endorser } from "fabric-common"; /** * Constant value holding the default $GOPATH in the Fabric CLI container as @@ -916,7 +918,37 @@ export class PluginLedgerConnectorFabric break; } case FabricContractInvocationType.Send: { - out = await contract.submitTransaction(fnName, ...params); + const tx = contract.createTransaction(fnName); + if (req.endorsingPeers) { + const { endorsingPeers } = req; + const channel = network.getChannel(); + + const allChannelEndorsers = (channel.getEndorsers() as unknown) as Array< + Endorser & { options: { pem: string } } + >; + + const endorsers = allChannelEndorsers + .map((endorser) => { + const certificate = Certificate.fromPEM( + (endorser.options.pem as unknown) as Buffer, + ); + return { certificate, endorser }; + }) + .filter( + ({ endorser, certificate }) => + endorsingPeers.includes(endorser.mspid) || + endorsingPeers.includes(certificate.issuer.organizationName), + ) + .map((it) => it.endorser); + + this.log.debug( + "%o endorsers: %o", + endorsers.length, + endorsers.map((it) => `${it.mspid}:${it.name}`), + ); + tx.setEndorsingPeers(endorsers); + } + out = await tx.submit(...params); success = true; break; } diff --git a/packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/run-transaction-endpoint-v1.test.ts b/packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/run-transaction-endpoint-v1.test.ts index 47a66a6c22..aafca696fe 100644 --- a/packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/run-transaction-endpoint-v1.test.ts +++ b/packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/run-transaction-endpoint-v1.test.ts @@ -231,6 +231,29 @@ test(testCase, async (t: Test) => { ); } + { + const req: RunTransactionRequest = { + signingCredential, + gatewayOptions: { + identity: keychainEntryKey, + wallet: { + json: keychainEntryValue, + }, + }, + channelName, + invocationType: FabricContractInvocationType.Send, + contractName, + methodName: "CreateAsset", + params: ["asset388", "green", "111", assetOwner, "299"], + endorsingPeers: ["org1.example.com", "Org2MSP"], + }; + + const res = await apiClient.runTransactionV1(req); + t.ok(res, "Create green asset response truthy OK"); + t.ok(res.data, "Create green asset response.data truthy OK"); + t.equal(res.status, 200, "Create green asset response.status=200 OK"); + } + { const res = await apiClient.runTransactionV1({ gatewayOptions: {