diff --git a/packages/cactus-plugin-keychain-azure-kv/src/main/typescript/web-services/get-keychain-entry-endpoint.ts b/packages/cactus-plugin-keychain-azure-kv/src/main/typescript/web-services/get-keychain-entry-endpoint.ts index e20e4ea417..5bf5259805 100644 --- a/packages/cactus-plugin-keychain-azure-kv/src/main/typescript/web-services/get-keychain-entry-endpoint.ts +++ b/packages/cactus-plugin-keychain-azure-kv/src/main/typescript/web-services/get-keychain-entry-endpoint.ts @@ -17,7 +17,7 @@ import { registerWebServiceEndpoint } from "@hyperledger/cactus-core"; import { PluginKeychainAzureKv } from "../plugin-keychain-azure-kv"; import OAS from "../../json/openapi.json"; -import { GetKeychainEntryRequest } from "../generated/openapi/typescript-axios"; +import { GetKeychainEntryRequestV1 } from "../generated/openapi/typescript-axios"; export interface IGetKeychainEntryEndpointOptions { logLevel?: LogLevelDesc; @@ -87,7 +87,7 @@ export class GetKeychainEntryEndpoint implements IWebServiceEndpoint { public async handleRequest(req: Request, res: Response): Promise { const reqTag = `${this.getVerbLowerCase()} - ${this.getPath()}`; this.log.debug(reqTag); - const { key } = req.body as GetKeychainEntryRequest; + const { key } = req.body as GetKeychainEntryRequestV1; try { const value = await this.options.connector.get(key); res.json({ diff --git a/packages/cactus-plugin-keychain-azure-kv/src/main/typescript/web-services/set-keychain-entry-endpoint.ts b/packages/cactus-plugin-keychain-azure-kv/src/main/typescript/web-services/set-keychain-entry-endpoint.ts index c8ff9c6743..40590ce5f5 100644 --- a/packages/cactus-plugin-keychain-azure-kv/src/main/typescript/web-services/set-keychain-entry-endpoint.ts +++ b/packages/cactus-plugin-keychain-azure-kv/src/main/typescript/web-services/set-keychain-entry-endpoint.ts @@ -17,7 +17,7 @@ import { registerWebServiceEndpoint } from "@hyperledger/cactus-core"; import { PluginKeychainAzureKv } from "../plugin-keychain-azure-kv"; import OAS from "../../json/openapi.json"; -import { SetKeychainEntryRequest } from "../generated/openapi/typescript-axios"; +import { SetKeychainEntryRequestV1 } from "../generated/openapi/typescript-axios"; export interface ISetKeychainEntryEndpointOptions { logLevel?: LogLevelDesc; @@ -88,7 +88,7 @@ export class SetKeychainEntryEndpoint implements IWebServiceEndpoint { const reqTag = `${this.getVerbLowerCase()} - ${this.getPath()}`; this.log.debug(reqTag); try { - const { key, value } = req.body as SetKeychainEntryRequest; + const { key, value } = req.body as SetKeychainEntryRequestV1; const resBody = await this.options.connector.set(key, value); res.json(resBody); } catch (ex) { diff --git a/packages/cactus-plugin-keychain-vault/src/main/typescript/web-services/get-keychain-entry-endpoint-v1.ts b/packages/cactus-plugin-keychain-vault/src/main/typescript/web-services/get-keychain-entry-endpoint-v1.ts index 1d2f22d67f..9504555cfb 100644 --- a/packages/cactus-plugin-keychain-vault/src/main/typescript/web-services/get-keychain-entry-endpoint-v1.ts +++ b/packages/cactus-plugin-keychain-vault/src/main/typescript/web-services/get-keychain-entry-endpoint-v1.ts @@ -16,7 +16,7 @@ import { registerWebServiceEndpoint } from "@hyperledger/cactus-core"; import OAS from "../../json/openapi.json"; import { PluginKeychainVault } from "../plugin-keychain-vault"; -import { GetKeychainEntryResponse } from "../generated/openapi/typescript-axios"; +import { GetKeychainEntryResponseV1 } from "../generated/openapi/typescript-axios"; export interface IGetKeychainEntryEndpointV1Options { logLevel?: LogLevelDesc; @@ -50,7 +50,7 @@ export class GetKeychainEntryEndpointV1 implements IWebServiceEndpoint { this.log.debug(`Instantiated ${this.className} OK`); } - public get oasPath(): typeof OAS.paths["/api/v1/plugins/@hyperledger/cactus-plugin-keychain-vault/get-keychain-entry"] { + public get oasPath(): (typeof OAS.paths)["/api/v1/plugins/@hyperledger/cactus-plugin-keychain-vault/get-keychain-entry"] { return OAS.paths[ "/api/v1/plugins/@hyperledger/cactus-plugin-keychain-vault/get-keychain-entry" ]; @@ -94,7 +94,7 @@ export class GetKeychainEntryEndpointV1 implements IWebServiceEndpoint { try { this.log.debug(`${tag} %o`, req.body); const value = await this.plugin.get(req.body.key); - const resBody: GetKeychainEntryResponse = { + const resBody: GetKeychainEntryResponseV1 = { key: req.body.key, value: value as string, }; diff --git a/packages/cactus-plugin-keychain-vault/src/test/typescript/integration/openapi/openapi-validation.test.ts b/packages/cactus-plugin-keychain-vault/src/test/typescript/integration/openapi/openapi-validation.test.ts index c7a296ef34..66a63d3c00 100644 --- a/packages/cactus-plugin-keychain-vault/src/test/typescript/integration/openapi/openapi-validation.test.ts +++ b/packages/cactus-plugin-keychain-vault/src/test/typescript/integration/openapi/openapi-validation.test.ts @@ -21,11 +21,11 @@ import { import { Configuration, DeleteKeychainEntryRequestV1, - GetKeychainEntryRequest, + GetKeychainEntryRequestV1, HasKeychainEntryRequestV1, IPluginKeychainVaultOptions, PluginKeychainVault, - SetKeychainEntryRequest, + SetKeychainEntryRequestV1, } from "../../../../main/typescript/public-api"; import { DefaultApi as KeychainVaultApi } from "../../../../main/typescript/public-api"; @@ -138,7 +138,7 @@ test(`${testCase}`, async (t: Test) => { try { await apiClient.setKeychainEntryV1({ value: value1, - } as SetKeychainEntryRequest); + } as SetKeychainEntryRequestV1); } catch (err) { const e = err as AxiosError<{ path: string }[]>; t2.equal( @@ -174,7 +174,7 @@ test(`${testCase}`, async (t: Test) => { test(`${testCase} - ${fGet} - ${cWithoutParams}`, async (t2: Test) => { try { - await apiClient.getKeychainEntryV1({} as GetKeychainEntryRequest); + await apiClient.getKeychainEntryV1({} as GetKeychainEntryRequestV1); } catch (err) { const e = err as AxiosError<{ path: string }[]>; t2.equal( @@ -214,7 +214,7 @@ test(`${testCase}`, async (t: Test) => { key: key1, value: value1, fake: 4, - } as SetKeychainEntryRequest); + } as SetKeychainEntryRequestV1); } catch (err) { const e = err as AxiosError<{ path: string }[]>; t2.equal( @@ -262,7 +262,7 @@ test(`${testCase}`, async (t: Test) => { await apiClient.getKeychainEntryV1({ key: key1, fake: 4, - } as GetKeychainEntryRequest); + } as GetKeychainEntryRequestV1); } catch (err) { const e = err as AxiosError<{ path: string }[]>; t2.equal( @@ -286,7 +286,7 @@ test(`${testCase}`, async (t: Test) => { await apiClient.deleteKeychainEntryV1({ key: key1, fake: 4, - } as GetKeychainEntryRequest); + } as GetKeychainEntryRequestV1); } catch (err) { const e = err as AxiosError; t2.equal( diff --git a/packages/cactus-plugin-ledger-connector-quorum/package.json b/packages/cactus-plugin-ledger-connector-quorum/package.json index e2ae8b9e4d..e62e8f0d5c 100644 --- a/packages/cactus-plugin-ledger-connector-quorum/package.json +++ b/packages/cactus-plugin-ledger-connector-quorum/package.json @@ -70,6 +70,7 @@ "socket.io-client": "4.5.4", "typescript-optional": "2.0.1", "web3": "1.6.1", + "web3-core-helpers": "1.6.1", "web3-eth-contract": "1.6.1", "web3-utils": "1.6.1", "web3js-quorum": "22.4.0" diff --git a/packages/cactus-plugin-ledger-connector-quorum/src/main/typescript/plugin-ledger-connector-quorum.ts b/packages/cactus-plugin-ledger-connector-quorum/src/main/typescript/plugin-ledger-connector-quorum.ts index 5884e95770..8ee1bec286 100644 --- a/packages/cactus-plugin-ledger-connector-quorum/src/main/typescript/plugin-ledger-connector-quorum.ts +++ b/packages/cactus-plugin-ledger-connector-quorum/src/main/typescript/plugin-ledger-connector-quorum.ts @@ -12,6 +12,10 @@ import Web3JsQuorum, { ISendRawTransaction, IPrivateTransactionReceipt, } from "web3js-quorum"; +import { + WebsocketProviderOptions, + HttpProviderOptions, +} from "web3-core-helpers"; import { AbiItem } from "web3-utils"; import { Contract } from "web3-eth-contract"; import { ContractSendMethod } from "web3-eth-contract"; @@ -84,6 +88,8 @@ export interface IPluginLedgerConnectorQuorumOptions prometheusExporter?: PrometheusExporter; pluginRegistry: PluginRegistry; privateUrl?: string; + wsProviderOptions?: WebsocketProviderOptions; + httpProviderOptions?: HttpProviderOptions; } export class PluginLedgerConnectorQuorum @@ -113,9 +119,20 @@ export class PluginLedgerConnectorQuorum private getWeb3Provider() { if (!this.options.rpcApiWsHost) { - return new Web3.providers.HttpProvider(this.options.rpcApiHttpHost); - } - return new Web3.providers.WebsocketProvider(this.options.rpcApiWsHost); + return this.options.httpProviderOptions + ? new Web3.providers.HttpProvider( + this.options.rpcApiHttpHost, + this.options.httpProviderOptions, + ) + : new Web3.providers.HttpProvider(this.options.rpcApiHttpHost); + } + + return this.options.wsProviderOptions + ? new Web3.providers.WebsocketProvider( + this.options.rpcApiWsHost, + this.options.wsProviderOptions, + ) + : new Web3.providers.WebsocketProvider(this.options.rpcApiWsHost); } constructor(public readonly options: IPluginLedgerConnectorQuorumOptions) { diff --git a/packages/cactus-plugin-ledger-connector-quorum/src/test/typescript/integration/plugin-ledger-connector-quorum/deploy-contract/v21.4.1-invoke-web3-method-v1.test.ts b/packages/cactus-plugin-ledger-connector-quorum/src/test/typescript/integration/plugin-ledger-connector-quorum/deploy-contract/v21.4.1-invoke-web3-method-v1.test.ts index 5b897746fa..6ff2ee0cbb 100644 --- a/packages/cactus-plugin-ledger-connector-quorum/src/test/typescript/integration/plugin-ledger-connector-quorum/deploy-contract/v21.4.1-invoke-web3-method-v1.test.ts +++ b/packages/cactus-plugin-ledger-connector-quorum/src/test/typescript/integration/plugin-ledger-connector-quorum/deploy-contract/v21.4.1-invoke-web3-method-v1.test.ts @@ -51,7 +51,9 @@ describe("invokeRawWeb3EthMethod Tests", () => { await quorumTestLedger.start(); const rpcApiHttpHost = await quorumTestLedger.getRpcApiHttpHost(); - log.debug("rpcApiHttpHost:", rpcApiHttpHost); + const getRpcApiWsHost = await quorumTestLedger.getRpcApiWsHost(); + log.warn("rpcApiHttpHost:", rpcApiHttpHost); + log.warn("getRpcApiWsHost:", getRpcApiWsHost); log.info("Create PluginLedgerConnectorQuorum..."); connector = new PluginLedgerConnectorQuorum({ diff --git a/packages/cactus-test-plugin-ledger-connector-quorum/src/test/typescript/integration/api-client/verifier-integration-with-quorum-connector.test.ts b/packages/cactus-test-plugin-ledger-connector-quorum/src/test/typescript/integration/api-client/verifier-integration-with-quorum-connector.test.ts index d0fae5441a..1e86af0deb 100644 --- a/packages/cactus-test-plugin-ledger-connector-quorum/src/test/typescript/integration/api-client/verifier-integration-with-quorum-connector.test.ts +++ b/packages/cactus-test-plugin-ledger-connector-quorum/src/test/typescript/integration/api-client/verifier-integration-with-quorum-connector.test.ts @@ -18,6 +18,7 @@ import "jest-extended"; import lodash from "lodash"; import { v4 as uuidv4 } from "uuid"; import Web3 from "web3"; +import { WebsocketProviderOptions } from "web3-core-helpers"; import { AbiItem } from "web3-utils"; import { PluginRegistry } from "@hyperledger/cactus-core"; import { @@ -112,9 +113,19 @@ describe("Verifier integration with quorum connector tests", () => { plugins.push(keychainPlugin); log.info("Create PluginLedgerConnectorQuorum..."); + + const wsProviderOptions: WebsocketProviderOptions = { + clientConfig: { + // Useful if requests are large + maxReceivedFrameSize: 100000000, + maxReceivedMessageSize: 100000000, + }, + }; + connector = new PluginLedgerConnectorQuorum({ rpcApiHttpHost: connectionProfile.quorum.member1.url, rpcApiWsHost: connectionProfile.quorum.member1.wsUrl, + wsProviderOptions: wsProviderOptions, logLevel: sutLogLevel, instanceId: uuidv4(), pluginRegistry: new PluginRegistry({ plugins: [keychainPlugin] }), @@ -270,6 +281,26 @@ describe("Verifier integration with quorum connector tests", () => { }; }); + test("Using verifier for calling getBlock method works", async () => { + const correctContract = {}; + const correctMethod = { + type: "web3Eth", + command: "getBlock", + }; + + const correctArgs: any = { args: ["latest"] }; + + const resultCorrect = await verifier.sendSyncRequest( + correctContract, + correctMethod, + correctArgs, + ); + + log.warn("verifier", verifier); + log.warn("###Results", resultCorrect); + // expect(resultCorrect.status).toEqual(200); + }); + test("Invalid web3EthContract calls are rejected by QuorumApiClient", async () => { // Define correct input parameters const correctContract: Record = lodash.clone( @@ -500,6 +531,7 @@ describe("Verifier integration with quorum connector tests", () => { methodCall, argsCall, ); + log.error(resultsCall); expect(resultsCall.status).toEqual(200); expect(resultsCall.data).toEqual(newName); }); diff --git a/packages/cactus-test-tooling/src/main/typescript/quorum/quorum-test-ledger.ts b/packages/cactus-test-tooling/src/main/typescript/quorum/quorum-test-ledger.ts index eb28870515..d89e7dfebe 100644 --- a/packages/cactus-test-tooling/src/main/typescript/quorum/quorum-test-ledger.ts +++ b/packages/cactus-test-tooling/src/main/typescript/quorum/quorum-test-ledger.ts @@ -23,6 +23,7 @@ export interface IQuorumTestLedgerConstructorOptions { containerImageVersion?: string; containerImageName?: string; rpcApiHttpPort?: number; + rpcApiWsPort?: number; logLevel?: LogLevelDesc; emitContainerLogs?: boolean; readonly envVars?: string[]; @@ -32,6 +33,7 @@ export const QUORUM_TEST_LEDGER_DEFAULT_OPTIONS = Object.freeze({ containerImageVersion: "2021-01-08-7a055c3", containerImageName: "ghcr.io/hyperledger/cactus-quorum-all-in-one", rpcApiHttpPort: 8545, + rpcApiWsPort: 8546, }); export const QUORUM_TEST_LEDGER_OPTIONS_JOI_SCHEMA: Joi.Schema = Joi.object().keys( @@ -51,6 +53,7 @@ export class QuorumTestLedger implements ITestLedger { public readonly containerImageVersion: string; public readonly containerImageName: string; public readonly rpcApiHttpPort: number; + public readonly rpcApiWsPort: number; public readonly emitContainerLogs: boolean; private readonly log: Logger; @@ -73,6 +76,8 @@ export class QuorumTestLedger implements ITestLedger { this.rpcApiHttpPort = options.rpcApiHttpPort || QUORUM_TEST_LEDGER_DEFAULT_OPTIONS.rpcApiHttpPort; + this.rpcApiWsPort = + options.rpcApiWsPort || QUORUM_TEST_LEDGER_DEFAULT_OPTIONS.rpcApiWsPort; this.envVars = options.envVars || []; @@ -102,9 +107,14 @@ export class QuorumTestLedger implements ITestLedger { public async getRpcApiHttpHost(): Promise { const ipAddress = "127.0.0.1"; - const hostPort = await this.getRpcApiPublicPort(); + const hostPort = await this.getRpcHttpApiPublicPort(); return `http://${ipAddress}:${hostPort}`; } + public async getRpcApiWsHost(): Promise { + const ipAddress = "127.0.0.1"; + const hostPort = await this.getRpcWsApiPublicPort(); + return `ws://${ipAddress}:${hostPort}`; + } public async getFileContents(filePath: string): Promise { const response: NodeJS.ReadableStream = await this.getContainer().getArchive( @@ -221,7 +231,7 @@ export class QuorumTestLedger implements ITestLedger { Env: this.envVars, ExposedPorts: { [`${this.rpcApiHttpPort}/tcp`]: {}, // quorum RPC - HTTP - "8546/tcp": {}, // quorum RPC - WebSocket + [`${this.rpcApiWsPort}/tcp`]: {}, // quorum RPC - WebSocket "8888/tcp": {}, // orion Client Port - HTTP "8080/tcp": {}, // orion Node Port - HTTP "9001/tcp": {}, // supervisord - HTTP @@ -339,7 +349,7 @@ export class QuorumTestLedger implements ITestLedger { } } - public async getRpcApiPublicPort(): Promise { + public async getRpcHttpApiPublicPort(): Promise { const fnTag = "QuorumTestLedger#getRpcApiPublicPort()"; const aContainerInfo = await this.getContainerInfo(); const { rpcApiHttpPort: thePort } = this; @@ -362,6 +372,29 @@ export class QuorumTestLedger implements ITestLedger { } } + public async getRpcWsApiPublicPort(): Promise { + const fnTag = "QuorumTestLedger#getRpcWsApiPublicPort()"; + const aContainerInfo = await this.getContainerInfo(); + const { rpcApiWsPort: thePort } = this; + const { Ports: ports } = aContainerInfo; + + if (ports.length < 1) { + throw new Error(`${fnTag} no ports exposed or mapped at all`); + } + const mapping = ports.find((x) => x.PrivatePort === thePort); + if (mapping) { + if (!mapping.PublicPort) { + throw new Error(`${fnTag} port ${thePort} mapped but not public`); + } else if (mapping.IP !== "0.0.0.0") { + throw new Error(`${fnTag} port ${thePort} mapped to localhost`); + } else { + return mapping.PublicPort; + } + } else { + throw new Error(`${fnTag} no mapping found for ${thePort}`); + } + } + public async getContainerIpAddress(): Promise { const fnTag = "QuorumTestLedger#getContainerIpAddress()"; const aContainerInfo = await this.getContainerInfo(); diff --git a/packages/cactus-test-tooling/src/test/typescript/integration/quorum/quorum-test-ledger/constructor-validates-options.test.ts b/packages/cactus-test-tooling/src/test/typescript/integration/quorum/quorum-test-ledger/constructor-validates-options.test.ts index 42cb3d4110..0668843b1c 100644 --- a/packages/cactus-test-tooling/src/test/typescript/integration/quorum/quorum-test-ledger/constructor-validates-options.test.ts +++ b/packages/cactus-test-tooling/src/test/typescript/integration/quorum/quorum-test-ledger/constructor-validates-options.test.ts @@ -35,7 +35,7 @@ tap.test("starts/stops/destroys a docker container", async (assert: any) => { assert.ok(ipAddress); assert.ok(ipAddress.length); - const hostPort: number = await ledger.getRpcApiPublicPort(); + const hostPort: number = await ledger.getRpcHttpApiPublicPort(); assert.ok(hostPort, "getRpcApiPublicPort() returns truthy OK"); assert.ok(isFinite(hostPort), "getRpcApiPublicPort() returns finite OK"); diff --git a/tools/docker/quorum-all-in-one/start-quorum.sh b/tools/docker/quorum-all-in-one/start-quorum.sh index 86e593616c..8ada58b928 100755 --- a/tools/docker/quorum-all-in-one/start-quorum.sh +++ b/tools/docker/quorum-all-in-one/start-quorum.sh @@ -43,6 +43,11 @@ geth \ --http.vhosts "*" \ --http.addr 0.0.0.0 \ --http.port 8545 \ + --ws \ + --wsaddr "0.0.0.0" \ + --wsport "8546" \ + --wsapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,${QUORUM_CONSENSUS:-raft} \ + --wsorigins "*" \ --http.api admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,${QUORUM_CONSENSUS:-raft} \ --port 21000 \ --allow-insecure-unlock \ diff --git a/yarn.lock b/yarn.lock index e0106dfccd..2ed4c756cb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6702,6 +6702,7 @@ __metadata: socket.io-client: 4.5.4 typescript-optional: 2.0.1 web3: 1.6.1 + web3-core-helpers: 1.6.1 web3-eth: 1.6.1 web3-eth-contract: 1.6.1 web3-utils: 1.6.1