From 223b7417c0db9ce6c2e3cd0780caa90c7357f7c0 Mon Sep 17 00:00:00 2001 From: aldousalvarez Date: Tue, 8 Oct 2024 09:19:50 +0800 Subject: [PATCH] test(test-plugin-ledger-connector-besu): jestify v21-sign-transaction-endpoint Primary Changes ---------------- packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/ integration/plugin-validator-besu/v21-sign-transaction-endpoint.test.ts Fixes #3565 Signed-off-by: aldousalvarez --- .taprc | 1 - jest.config.js | 1 - .../v21-sign-transaction-endpoint.test.ts | 297 +++++++++--------- 3 files changed, 151 insertions(+), 148 deletions(-) diff --git a/.taprc b/.taprc index 21648be886..e6e75775dd 100644 --- a/.taprc +++ b/.taprc @@ -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 diff --git a/jest.config.js b/jest.config.js index 4639041b3d..8bb098ea00 100644 --- a/jest.config.js +++ b/jest.config.js @@ -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`, diff --git a/packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-validator-besu/v21-sign-transaction-endpoint.test.ts b/packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-validator-besu/v21-sign-transaction-endpoint.test.ts index 7ca2508a1a..294db157be 100644 --- a/packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-validator-besu/v21-sign-transaction-endpoint.test.ts +++ b/packages/cactus-test-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-validator-besu/v21-sign-transaction-endpoint.test.ts @@ -1,4 +1,4 @@ -import test, { Test } from "tape-promise/tape"; +import "jest-extended"; import { v4 as uuidv4 } from "uuid"; import { createServer } from "http"; @@ -18,6 +18,7 @@ import { Secp256k1Keys, KeyFormat, LogLevelDesc, + LoggerProvider, } from "@hyperledger/cactus-common"; import { @@ -37,164 +38,168 @@ import { PluginRegistry } from "@hyperledger/cactus-core"; import { PluginKeychainMemory } from "@hyperledger/cactus-plugin-keychain-memory"; +import axios from "axios"; + 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(), +describe(testCase, () => { + const log = LoggerProvider.getOrCreate({ + label: "v21-get-transaction-endpoint.test.ts", + level: logLevel, }); - - const httpServer1 = createServer(); - await new Promise((resolve, reject) => { - httpServer1.once("error", reject); - httpServer1.once("listening", resolve); - httpServer1.listen(0, "127.0.0.1"); - }); - 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; + + beforeAll(async () => { + const pruning = pruneDockerAllIfGithubAction({ logLevel }); + await expect(pruning).resolves.toBeTruthy(); + await besuTestLedger.start(); + }); - const tearDown = async () => { + 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 httpServer1 = createServer(); + await new Promise((resolve, reject) => { + httpServer1.once("error", reject); + httpServer1.once("listening", resolve); + httpServer1.listen(0, "127.0.0.1"); + }); + const addressInfo1 = httpServer1.address() as AddressInfo; + log.debug(`HttpServer1 AddressInfo: ${JSON.stringify(addressInfo1)}`); + + const node1Host = `http://${addressInfo1.address}:${addressInfo1.port}`; + log.debug(`Cactus Node 1 Host: ${node1Host}`); + + 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); + + apiServer = new ApiServer({ + httpServerApi: httpServer1, + 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(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, }; - 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 configuration = new BesuApiClientOptions({ basePath: node1Host }); + 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"); + } + } + }); });