Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(quorum): add WebsocketProvider options to quorum LP #2448

Merged
merged 2 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -87,7 +87,7 @@ export class GetKeychainEntryEndpoint implements IWebServiceEndpoint {
public async handleRequest(req: Request, res: Response): Promise<void> {
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({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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"
];
Expand Down Expand Up @@ -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,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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(
Expand All @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ import Web3JsQuorum, {
ISendRawTransaction,
IPrivateTransactionReceipt,
} from "web3js-quorum";
import {
WebsocketProviderOptions,
HttpProviderOptions,
} from "web3-core-helpers";
petermetz marked this conversation as resolved.
Show resolved Hide resolved
import { AbiItem } from "web3-utils";
import { Contract } from "web3-eth-contract";
import { ContractSendMethod } from "web3-eth-contract";
Expand Down Expand Up @@ -84,6 +88,8 @@ export interface IPluginLedgerConnectorQuorumOptions
prometheusExporter?: PrometheusExporter;
pluginRegistry: PluginRegistry;
privateUrl?: string;
wsProviderOptions?: WebsocketProviderOptions;
httpProviderOptions?: HttpProviderOptions;
}

export class PluginLedgerConnectorQuorum
Expand Down Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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] }),
Expand Down Expand Up @@ -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<string, unknown> = lodash.clone(
Expand Down Expand Up @@ -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);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export interface IQuorumTestLedgerConstructorOptions {
containerImageVersion?: string;
containerImageName?: string;
rpcApiHttpPort?: number;
rpcApiWsPort?: number;
logLevel?: LogLevelDesc;
emitContainerLogs?: boolean;
readonly envVars?: string[];
Expand All @@ -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(
Expand All @@ -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;
Expand All @@ -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 || [];

Expand Down Expand Up @@ -102,9 +107,14 @@ export class QuorumTestLedger implements ITestLedger {

public async getRpcApiHttpHost(): Promise<string> {
const ipAddress = "127.0.0.1";
const hostPort = await this.getRpcApiPublicPort();
const hostPort = await this.getRpcHttpApiPublicPort();
return `http://${ipAddress}:${hostPort}`;
}
public async getRpcApiWsHost(): Promise<string> {
const ipAddress = "127.0.0.1";
const hostPort = await this.getRpcWsApiPublicPort();
return `ws://${ipAddress}:${hostPort}`;
}

public async getFileContents(filePath: string): Promise<string> {
const response: NodeJS.ReadableStream = await this.getContainer().getArchive(
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -339,7 +349,7 @@ export class QuorumTestLedger implements ITestLedger {
}
}

public async getRpcApiPublicPort(): Promise<number> {
public async getRpcHttpApiPublicPort(): Promise<number> {
const fnTag = "QuorumTestLedger#getRpcApiPublicPort()";
const aContainerInfo = await this.getContainerInfo();
const { rpcApiHttpPort: thePort } = this;
Expand All @@ -362,6 +372,29 @@ export class QuorumTestLedger implements ITestLedger {
}
}

public async getRpcWsApiPublicPort(): Promise<number> {
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<string> {
const fnTag = "QuorumTestLedger#getContainerIpAddress()";
const aContainerInfo = await this.getContainerInfo();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand Down
5 changes: 5 additions & 0 deletions tools/docker/quorum-all-in-one/start-quorum.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
1 change: 1 addition & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading