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

test(test-plugin-ledger-connector-besu): jestify v21-sign-transaction… #12

Closed
wants to merge 1 commit into from
Closed
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
4 changes: 2 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2373,15 +2373,15 @@ jobs:
needs:
- build-dev
- compute_changed_packages
if: needs.compute_changed_packages.outputs.plugin-ledger-connector-fabric-changed == 'true'
if: needs.compute_changed_packages.outputs.plugin-ledger-connector-besu-changed == 'true'
env:
FULL_BUILD_DISABLED: true
JEST_TEST_PATTERN: packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/(unit|integration|benchmark)/.*/*.test.ts
JEST_TEST_RUNNER_DISABLED: false
JEST_TEST_COVERAGE_PATH: ./code-coverage-ts/ctp-ledger-connector-besu
JEST_TEST_CODE_COVERAGE_ENABLED: true
TAPE_TEST_PATTERN: >-
--files={./packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-validator-besu/get-block-endpoint.test.ts,./packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-validator-besu/get-past-logs-endpoint.test.ts,./packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-validator-besu/get-transaction-endpoint.test.ts,./packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-validator-besu/v21-get-block-endpoint.test.ts,./packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-validator-besu/v21-get-past-logs-endpoint.test.ts,./packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-validator-besu/v21-sign-transaction-endpoint.test.ts}
--files={./packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-validator-besu/get-block-endpoint.test.ts,./packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-validator-besu/get-past-logs-endpoint.test.ts,./packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-validator-besu/get-transaction-endpoint.test.ts,./packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-validator-besu/v21-get-block-endpoint.test.ts,./packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-validator-besu/v21-get-past-logs-endpoint.test.ts}
TAPE_TEST_RUNNER_DISABLED: false
runs-on: ubuntu-22.04
steps:
Expand Down
1 change: 0 additions & 1 deletion .taprc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ files:
- ./packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-validator-besu/get-past-logs-endpoint.test.ts
- ./packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-validator-besu/get-transaction-endpoint.test.ts
- ./packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-validator-besu/get-block-endpoint.test.ts
- ./packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-validator-besu/v21-sign-transaction-endpoint.test.ts
- ./packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/identity-client.test.ts
- ./packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/deploy-cc-from-javascript-source.test.ts
- ./packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/run-transaction-with-identities.test.ts
Expand Down
1 change: 0 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ module.exports = {
`./packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-validator-besu/get-past-logs-endpoint.test.ts`,
`./packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-validator-besu/get-transaction-endpoint.test.ts`,
`./packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-validator-besu/get-block-endpoint.test.ts`,
`./packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-validator-besu/v21-sign-transaction-endpoint.test.ts`,
`./packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/identity-client.test.ts`,
`./packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/deploy-cc-from-javascript-source.test.ts`,
`./packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/run-transaction-with-identities.test.ts`,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import test, { Test } from "tape-promise/tape";
import "jest-extended";

import axios from "axios";
import { v4 as uuidv4 } from "uuid";
import { createServer } from "http";
import KeyEncoder from "key-encoder";
Expand All @@ -18,6 +19,7 @@ import {
Secp256k1Keys,
KeyFormat,
LogLevelDesc,
LoggerProvider,
} from "@hyperledger/cactus-common";

import {
Expand All @@ -40,161 +42,163 @@ import { PluginKeychainMemory } from "@hyperledger/cactus-plugin-keychain-memory
const testCase = "Test sign transaction endpoint";
const logLevel: LogLevelDesc = "TRACE";

test("BEFORE " + testCase, async (t: Test) => {
const pruning = pruneDockerAllIfGithubAction({ logLevel });
await t.doesNotReject(pruning, "Pruning didn't throw OK");
t.end();
});

test(testCase, async (t: Test) => {
const keyEncoder: KeyEncoder = new KeyEncoder("secp256k1");
const keychainId = uuidv4();
const keychainRef = uuidv4();

const { privateKey } = Secp256k1Keys.generateKeyPairsBuffer();
const keyHex = privateKey.toString("hex");
const pem = keyEncoder.encodePrivate(keyHex, KeyFormat.Raw, KeyFormat.PEM);

const keychain = new PluginKeychainMemory({
backend: new Map([[keychainRef, pem]]),
keychainId,
logLevel,
instanceId: uuidv4(),
});

const httpServer1 = createServer();
await new Promise((resolve, reject) => {
httpServer1.once("error", reject);
httpServer1.once("listening", resolve);
httpServer1.listen(0, "127.0.0.1");
describe(testCase, () => {
const log = LoggerProvider.getOrCreate({
label: "v21-get-transaction-endpoint.test.ts",
level: logLevel,
});
const addressInfo1 = httpServer1.address() as AddressInfo;
t.comment(`HttpServer1 AddressInfo: ${JSON.stringify(addressInfo1)}`);
const node1Host = `http://${addressInfo1.address}:${addressInfo1.port}`;
t.comment(`Cactus Node 1 Host: ${node1Host}`);

const containerImageVersion = "2021-08-24--feat-1244";
const containerImageName =
"ghcr.io/hyperledger/cactus-besu-21-1-6-all-in-one";
const besuOptions = { containerImageName, containerImageVersion };
const besuTestLedger = new BesuTestLedger(besuOptions);
await besuTestLedger.start();
let apiServer: ApiServer;

const tearDown = async () => {
beforeAll(async () => {
const pruning = pruneDockerAllIfGithubAction({ logLevel });
await expect(pruning).resolves.toBeTruthy();
await besuTestLedger.start();
});

afterAll(async () => {
await besuTestLedger.stop();
await besuTestLedger.destroy();
await pruneDockerAllIfGithubAction({ logLevel });
};

test.onFinish(tearDown);

const rpcApiHttpHost = await besuTestLedger.getRpcApiHttpHost();
const rpcApiWsHost = await besuTestLedger.getRpcApiWsHost();

const jsObjectSignerOptions: IJsObjectSignerOptions = {
privateKey: keyHex,
logLevel,
};
const jsObjectSigner = new JsObjectSigner(jsObjectSignerOptions);

// 2. Instantiate plugin registry which will provide the web service plugin with the key value storage plugin
const pluginRegistry = new PluginRegistry({ plugins: [keychain] });

// 3. Instantiate the web service consortium plugin
const options: IPluginLedgerConnectorBesuOptions = {
instanceId: uuidv4(),
rpcApiHttpHost,
rpcApiWsHost,
pluginRegistry,
logLevel,
};
const pluginValidatorBesu = new PluginLedgerConnectorBesu(options);

// 4. Create the API Server object that we embed in this test
const configService = new ConfigService();
const apiServerOptions = await configService.newExampleConfig();
apiServerOptions.authorizationProtocol = AuthorizationProtocol.NONE;
apiServerOptions.configFile = "";
apiServerOptions.apiCorsDomainCsv = "*";
apiServerOptions.apiPort = addressInfo1.port;
apiServerOptions.cockpitPort = 0;
apiServerOptions.apiTlsEnabled = false;
const config = await configService.newExampleConfigConvict(apiServerOptions);

pluginRegistry.add(pluginValidatorBesu);

const apiServer = new ApiServer({
httpServerApi: httpServer1,
config: config.getProperties(),
pluginRegistry,
});

// 5. make sure the API server is shut down when the testing if finished.
test.onFinish(() => apiServer.shutdown());

// 6. Start the API server which is now listening on port A and it's healthcheck works through the main SDK
await apiServer.start();

// 7. Instantiate the main SDK dynamically with whatever port the API server ended up bound to (port 0)
t.comment(`AddressInfo: ${JSON.stringify(addressInfo1)}`);

const web3Provider = new Web3.providers.HttpProvider(rpcApiHttpHost);
const web3 = new Web3(web3Provider);
const web3JsQuorum: IWeb3Quorum = Web3JsQuorum(web3);

const orionKeyPair = await besuTestLedger.getOrionKeyPair();
const besuKeyPair = await besuTestLedger.getBesuKeyPair();

const besuPrivateKey = besuKeyPair.privateKey.toLowerCase().startsWith("0x")
? besuKeyPair.privateKey.substring(2)
: besuKeyPair.privateKey; // besu node's private key

const contractOptions = {
data: `0x123`,
// privateFrom : Orion public key of the sender.
privateFrom: orionKeyPair.publicKey,
// privateFor : Orion public keys of recipients or privacyGroupId: Privacy group to receive the transaction
privateFor: [orionKeyPair.publicKey],
// privateKey: Ethereum private key with which to sign the transaction.
privateKey: besuPrivateKey,
};

const transactionHash =
await web3JsQuorum.priv.generateAndSendRawTransaction(contractOptions);

const transaction = await web3.eth.getTransaction(transactionHash);
const singData = jsObjectSigner.sign(transaction.input);
const signDataHex = Buffer.from(singData).toString("hex");

const request: SignTransactionRequest = {
keychainId,
keychainRef,
transactionHash: transactionHash,
};

const configuration = new BesuApiClientOptions({ basePath: node1Host });
const api = new BesuApiClient(configuration);

// Test for 200 valid response test case
const res = await api.signTransactionV1(request);
t.ok(res, "API response object is truthy");
t.deepEquals(signDataHex, res.data.signature, "Signature data are equal");

// Test for 404 Transaction not found test case
try {
const notFoundRequest: SignTransactionRequest = {
keychainId: "fake",
keychainRef: "fake",
transactionHash:
"0x46eac4d1d1ff81837698cbab38862a428ddf042f92855a72010de2771a7b704d",
afterAll(async () => {
await apiServer.shutdown();
});

test(testCase, async () => {
const keyEncoder: KeyEncoder = new KeyEncoder("secp256k1");
const keychainId = uuidv4();
const keychainRef = uuidv4();

const { privateKey } = Secp256k1Keys.generateKeyPairsBuffer();
const keyHex = privateKey.toString("hex");
const pem = keyEncoder.encodePrivate(keyHex, KeyFormat.Raw, KeyFormat.PEM);

const keychain = new PluginKeychainMemory({
backend: new Map([[keychainRef, pem]]),
keychainId,
logLevel,
instanceId: uuidv4(),
});

const httpServer = createServer();
await new Promise((resolve, reject) => {
httpServer.once("error", reject);
httpServer.once("listening", resolve);
httpServer.listen(0, "127.0.0.1");
});
const addressInfo = httpServer.address() as AddressInfo;
log.debug(`HttpServer1 AddressInfo: ${JSON.stringify(addressInfo)}`);

const nodeHost = `http://${addressInfo.address}:${addressInfo.port}`;
log.debug(`Cactus Node 1 Host: ${nodeHost}`);

const rpcApiHttpHost = await besuTestLedger.getRpcApiHttpHost();
const rpcApiWsHost = await besuTestLedger.getRpcApiWsHost();

const jsObjectSignerOptions: IJsObjectSignerOptions = {
privateKey: keyHex,
logLevel,
};
const jsObjectSigner = new JsObjectSigner(jsObjectSignerOptions);

// 2. Instantiate plugin registry which will provide the web service plugin with the key value storage plugin
const pluginRegistry = new PluginRegistry({ plugins: [keychain] });

// 3. Instantiate the web service consortium plugin
const options: IPluginLedgerConnectorBesuOptions = {
instanceId: uuidv4(),
rpcApiHttpHost,
rpcApiWsHost,
pluginRegistry,
logLevel,
};
const pluginValidatorBesu = new PluginLedgerConnectorBesu(options);

// 4. Create the API Server object that we embed in this test
const configService = new ConfigService();
const apiServerOptions = await configService.newExampleConfig();
apiServerOptions.authorizationProtocol = AuthorizationProtocol.NONE;
apiServerOptions.configFile = "";
apiServerOptions.apiCorsDomainCsv = "*";
apiServerOptions.apiPort = addressInfo.port;
apiServerOptions.cockpitPort = 0;
apiServerOptions.apiTlsEnabled = false;
const config =
await configService.newExampleConfigConvict(apiServerOptions);

pluginRegistry.add(pluginValidatorBesu);

apiServer = new ApiServer({
httpServerApi: httpServer,
config: config.getProperties(),
pluginRegistry,
});

// 6. Start the API server which is now listening on port A and it's healthcheck works through the main SDK
await apiServer.start();

// 7. Instantiate the main SDK dynamically with whatever port the API server ended up bound to (port 0)
console.log(`AddressInfo: ${JSON.stringify(addressInfo)}`);

const web3Provider = new Web3.providers.HttpProvider(rpcApiHttpHost);
const web3 = new Web3(web3Provider);
const web3JsQuorum: IWeb3Quorum = Web3JsQuorum(web3);

const orionKeyPair = await besuTestLedger.getOrionKeyPair();
const besuKeyPair = await besuTestLedger.getBesuKeyPair();

const besuPrivateKey = besuKeyPair.privateKey.toLowerCase().startsWith("0x")
? besuKeyPair.privateKey.substring(2)
: besuKeyPair.privateKey; // besu node's private key

const contractOptions = {
data: `0x123`,
// privateFrom : Orion public key of the sender.
privateFrom: orionKeyPair.publicKey,
// privateFor : Orion public keys of recipients or privacyGroupId: Privacy group to receive the transaction
privateFor: [orionKeyPair.publicKey],
// privateKey: Ethereum private key with which to sign the transaction.
privateKey: besuPrivateKey,
};
await api.signTransactionV1(notFoundRequest);
} catch (error) {
t.equal(error.response.status, 404, "HTTP response status are equal");
t.equal(
error.response.statusText,
"Transaction not found",
"Response text are equal",
);
}

const transactionHash =
await web3JsQuorum.priv.generateAndSendRawTransaction(contractOptions);

const transaction = await web3.eth.getTransaction(transactionHash);
const singData = jsObjectSigner.sign(transaction.input);
const signDataHex = Buffer.from(singData).toString("hex");

const request: SignTransactionRequest = {
keychainId,
keychainRef,
transactionHash: transactionHash,
};

const configuration = new BesuApiClientOptions({ basePath: nodeHost });
const api = new BesuApiClient(configuration);

const res = await api.signTransactionV1(request);
expect(res).toBeTruthy();
expect(signDataHex).toBe(res.data.signature);

try {
const notFoundRequest: SignTransactionRequest = {
keychainId: "fake",
keychainRef: "fake",
transactionHash:
"0x46eac4d1d1ff81837698cbab38862a428ddf042f92855a72010de2771a7b704d",
};
await api.signTransactionV1(notFoundRequest);
} catch (error) {
if (axios.isAxiosError(error)) {
expect(error.response?.status).toEqual(404);
expect(error.response?.statusText).toEqual("Transaction not found");
}
}
});
});
Loading