From 6f9768c9e98febb35d4580cae01fb6c86b6a9c48 Mon Sep 17 00:00:00 2001 From: Sandeep Nishad Date: Sat, 23 Dec 2023 02:01:03 +0530 Subject: [PATCH] feat(fabric-driver): added weaver fabric driver as cacti plugin package fix(fabric-driver): yarn lint errors Signed-off-by: Sandeep Nishad --- .../package.json | 76 +++++++++++++++++++ .../readme.md | 15 ++++ .../src/main/typescript | 1 + .../drivers/fabric-driver/server/events.ts | 14 ++-- .../fabric-driver/server/fabric-code.ts | 6 +- .../drivers/fabric-driver/server/listener.ts | 22 ++---- .../drivers/fabric-driver/server/server.ts | 15 +--- .../fabric-driver/server/walletSetup.ts | 2 +- yarn.lock | 6 ++ 9 files changed, 117 insertions(+), 40 deletions(-) create mode 100644 packages/cacti-plugin-weaver-driver-fabric/package.json create mode 100644 packages/cacti-plugin-weaver-driver-fabric/readme.md create mode 120000 packages/cacti-plugin-weaver-driver-fabric/src/main/typescript diff --git a/packages/cacti-plugin-weaver-driver-fabric/package.json b/packages/cacti-plugin-weaver-driver-fabric/package.json new file mode 100644 index 00000000000..39e35bf8e7c --- /dev/null +++ b/packages/cacti-plugin-weaver-driver-fabric/package.json @@ -0,0 +1,76 @@ +{ + "name": "@hyperledger/cacti-plugin-weaver-driver-fabric", + "version": "2.0.0-alpha.2", + "description": "Driver Server for communication with a Fabric Network as part of weaver data sharing protocol", + "keywords": [ + "Hyperledger", + "cacti", + "Integration", + "Blockchain", + "Distributed Ledger Technology", + "Weaver" + ], + "homepage": "https://github.com/hyperledger/cacti#readme", + "bugs": { + "url": "https://github.com/hyperledger/cacti/issues" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/hyperledger/cacti.git" + }, + "license": "Apache-2.0", + "author": { + "name": "Hyperledger cacti Contributors", + "email": "cacti@lists.hyperledger.org", + "url": "https://www.hyperledger.org/use/cacti" + }, + "contributors": [ + { + "name": "Please add yourself to the list of contributors", + "email": "your.name@example.com", + "url": "https://example.com" + }, + { + "name": "Venkatraman Ramakrishna", + "email": "vramakr2@in.ibm.com", + "url": "https://researcher.watson.ibm.com/researcher/view.php?person=in-vramakr2" + }, + { + "name": "Sandeep Nishad", + "email": "sandeep.nishad1@ibm.com", + "url": "https://github.com/sandeepnRES" + }, + { + "name": "Krishnasuri Narayanam", + "email": "knaraya3@in.ibm.com", + "url": "https://research.ibm.com/people/krishnasuri-narayanam" + } + ], + "main": "dist/lib/main/typescript/index.js", + "module": "dist/lib/main/typescript/index.js", + "types": "dist/lib/main/typescript/index.d.ts", + "files": [ + "dist/*" + ], + "scripts": { + "watch": "npm-watch", + "build": "cd src/main/typescript && make build", + "build-local": "cd src/main/typescript && make build-local", + "build-image": "cd src/main/typescript && make build-image", + "build-image-local": "cd src/main/typescript && make build-image-local", + "publish": "cd src/main/typescript && make push-image && make push-image-latest", + "postpublish": "cd src/main/typescript && make push-image-latest", + "clean": "cd src/main/typescript && make clean", + "clean-local": "cd src/main/typescript && make clean-local" + }, + "engines": { + "node": ">=18", + "npm": ">=8" + }, + "publishConfig": { + "access": "public" + }, + "browserMinified": "dist/cacti-weaver-driver-fabric.web.umd.min.js", + "mainMinified": "dist/cacti-weaver-driver-fabric.node.umd.min.js", + "watch": {} +} diff --git a/packages/cacti-plugin-weaver-driver-fabric/readme.md b/packages/cacti-plugin-weaver-driver-fabric/readme.md new file mode 100644 index 00000000000..7a504e1aadd --- /dev/null +++ b/packages/cacti-plugin-weaver-driver-fabric/readme.md @@ -0,0 +1,15 @@ + +# Cacti Fabric-Driver + +The term "driver" has been used in Weaver parlance, and is synonymous with "connector" as used in Cactus (and not in Cacti). Both terms refer to a module with an interface and functions to "connect" to a ledger of a given DLT type and "drive" transactions through that ledger for querying and state update purposes whenever required in the context of a cross-network transaction. +There are some distinctive features of the Weaver Fabric driver that are not covered by the Cactus Fabric connector package, which is why the two continue to co-exist at this time. Our goal is to eventually merge them into a single connector/driver package that offers both the distinctive and overlapping features of both the existing packages. + +For detailed information about fabric driver visit [here](src/main/typescript/readme.md). + +To use fabric-driver in your application please refer [documentation](https://hyperledger.github.io/cacti/weaver/getting-started/guide/). + + diff --git a/packages/cacti-plugin-weaver-driver-fabric/src/main/typescript b/packages/cacti-plugin-weaver-driver-fabric/src/main/typescript new file mode 120000 index 00000000000..34419c8b221 --- /dev/null +++ b/packages/cacti-plugin-weaver-driver-fabric/src/main/typescript @@ -0,0 +1 @@ +../../../../weaver/core/drivers/fabric-driver \ No newline at end of file diff --git a/weaver/core/drivers/fabric-driver/server/events.ts b/weaver/core/drivers/fabric-driver/server/events.ts index b646028a18a..20c9bd61033 100644 --- a/weaver/core/drivers/fabric-driver/server/events.ts +++ b/weaver/core/drivers/fabric-driver/server/events.ts @@ -66,7 +66,7 @@ async function subscribeEventHelper( if (newRequestId == requestId) { // event being subscribed for the first time // Start an appropriate type of event listener for this event subscription if one is not already active - const [listenerHandle, error] = await handlePromise( + const [, error] = await handlePromise( registerListenerForEventSubscription( call_request.getEventMatcher()!, network_name, @@ -74,7 +74,7 @@ async function subscribeEventHelper( ); if (error) { // Need to delete subscription in database too, for consistency - const [deletedSubscription, err] = await handlePromise( + const [, err] = await handlePromise( deleteEventSubscription( call_request.getEventMatcher()!, newRequestId, @@ -212,7 +212,7 @@ async function addEventSubscription( try { // fetch the current values in the DB against the given key - var subscriptionsSerialized: string = (await db.read(key)) as string; + const subscriptionsSerialized: string = (await db.read(key)) as string; subscriptions = JSON.parse(subscriptionsSerialized); logger.debug(`existing subscriptions.length: ${subscriptions.length}`); @@ -264,7 +264,7 @@ async function addEventSubscription( } logger.debug(`new subscriptions.length: ${subscriptions.length}`); - subscriptionsSerialized = JSON.stringify(subscriptions); + const subscriptionsSerialized = JSON.stringify(subscriptions); // insert the value against key in the DB (it can be the scenario of a new key addition, or update to the value of an existing key) await db.insert(key, subscriptionsSerialized); await db.close(); @@ -302,7 +302,7 @@ const deleteEventSubscription = async ( ); try { // fetch the current values in the DB against the given key - var subscriptionsSerialized: string = (await db.read(key)) as string; + const subscriptionsSerialized: string = (await db.read(key)) as string; subscriptions = JSON.parse(subscriptionsSerialized); logger.debug(`subscriptions.length: ${subscriptions.length}`); @@ -341,7 +341,7 @@ const deleteEventSubscription = async ( if (subscriptions.length == 0) { await db.delete(key); } else { - subscriptionsSerialized = JSON.stringify(subscriptions); + const subscriptionsSerialized = JSON.stringify(subscriptions); await db.insert(key, subscriptionsSerialized); } @@ -505,7 +505,6 @@ async function writeExternalStateHelper( const ctx: eventsPb.ContractTransaction = writeExternalStateMessage.getCtx(); const keyCert = await getDriverKeyCert(); - const requestId: string = viewPayload.getRequestId(); if (!viewPayload.getError()) { const interopArgIndices = [], viewsSerializedBase64 = [], @@ -568,6 +567,7 @@ async function writeExternalStateHelper( gateway.disconnect(); throw responseError; } + logger.debug(`write external state response: ${response}`); logger.debug(`write successful`); gateway.disconnect(); } else { diff --git a/weaver/core/drivers/fabric-driver/server/fabric-code.ts b/weaver/core/drivers/fabric-driver/server/fabric-code.ts index a68b97d26d8..858a9dbb604 100644 --- a/weaver/core/drivers/fabric-driver/server/fabric-code.ts +++ b/weaver/core/drivers/fabric-driver/server/fabric-code.ts @@ -11,7 +11,6 @@ import * as fs from "fs"; import query_pb from "@hyperledger/cacti-weaver-protos-js/common/query_pb"; import view_data from "@hyperledger/cacti-weaver-protos-js/fabric/view_data_pb"; import proposalResponse from "@hyperledger/cacti-weaver-protos-js/peer/proposal_response_pb"; -import interopPayload from "@hyperledger/cacti-weaver-protos-js/common/interop_payload_pb"; import state_pb from "@hyperledger/cacti-weaver-protos-js/common/state_pb"; import { Certificate } from "@fidm/x509"; import { getConfig } from "./walletSetup"; @@ -153,7 +152,7 @@ async function invoke( let proposalRequest; if (identities.length > 0) { const endorserList = endorsers.filter((endorser: Endorser) => { - //@ts-ignore + //@ts-expect-error: should expect string const cert = Certificate.fromPEM(endorser.options.pem); const orgName = cert.issuer.organizationName; return ( @@ -182,8 +181,7 @@ async function invoke( const viewPayload = new view_data.FabricView(); const endorsedProposalResponses: view_data.FabricView.EndorsedProposalResponse[] = []; - //TODO Fix ts error - //@ts-ignore + let endorsementCounter = 0; proposalResponseResult.responses.forEach((response) => { const endorsement = new proposalResponse.Endorsement(); diff --git a/weaver/core/drivers/fabric-driver/server/listener.ts b/weaver/core/drivers/fabric-driver/server/listener.ts index 4014d47ebb6..17ce15ff52c 100644 --- a/weaver/core/drivers/fabric-driver/server/listener.ts +++ b/weaver/core/drivers/fabric-driver/server/listener.ts @@ -9,12 +9,8 @@ import { BlockDecoder } from "fabric-common/index"; import { Gateway, Network, - Contract, - ContractEvent, BlockListener, - ContractListener, BlockEvent, - ListenerOptions, } from "fabric-network"; import query_pb from "@hyperledger/cacti-weaver-protos-js/common/query_pb"; import events_pb from "@hyperledger/cacti-weaver-protos-js/common/events_pb"; @@ -24,13 +20,10 @@ import { handlePromise, relayCallback, getRelayClientForEventPublish, - delay, } from "./utils"; import { DBConnector, LevelDBConnector, - DBLockedError, - DBKeyNotFoundError, } from "./dbConnector"; import logger from "./logger"; @@ -242,8 +235,7 @@ const initBlockEventListenerForChannel = async ( channelId: string, ): Promise => { const listener: BlockListener = async (event: BlockEvent) => { - let bh_db: DBConnector; - bh_db = new LevelDBConnector(DB_NAME!, DB_OPEN_TIMEOUT); + const bh_db: DBConnector = new LevelDBConnector(DB_NAME!, DB_OPEN_TIMEOUT); await bh_db.open(); try { const lastBlockNum = await getLastReadBlockNumber(bh_db, channelId); @@ -309,8 +301,7 @@ const registerListenerForEventSubscription = async ( globalLedgerListenerCount.get(channelId) + 1, ); } else { - let bh_db: DBConnector; - bh_db = new LevelDBConnector(DB_NAME!, DB_OPEN_TIMEOUT); + const bh_db: DBConnector = new LevelDBConnector(DB_NAME!, DB_OPEN_TIMEOUT); await bh_db.open(); try { const currBlockNum = await getCurrBlockNumber(network, channelId); @@ -373,8 +364,7 @@ const unregisterListenerForEventSubscription = async ( ); return true; } else { - let bh_db: DBConnector; - bh_db = new LevelDBConnector(DB_NAME!, DB_OPEN_TIMEOUT); + const bh_db: DBConnector = new LevelDBConnector(DB_NAME!, DB_OPEN_TIMEOUT); await bh_db.open(); try { // Set DB Height to -1 if no listener running @@ -411,7 +401,7 @@ const loadEventSubscriptionsFromStorage = async ( const eventMatchers = await readAllEventMatchers(); for (const eventMatcher of eventMatchers) { try { - const listenerHandle = await registerListenerForEventSubscription( + await registerListenerForEventSubscription( eventMatcher, networkName, ); @@ -478,12 +468,10 @@ async function getCurrBlockNumber( const monitorBlockForMissedEvents = async (networkName: string) => { logger.debug("############### Monitor Begin #################"); // Create connection to a database - let bh_db: DBConnector; - bh_db = new LevelDBConnector(DB_NAME!, DB_OPEN_TIMEOUT); + const bh_db: DBConnector = new LevelDBConnector(DB_NAME!, DB_OPEN_TIMEOUT); await bh_db.open(); try { if (networkGatewayMap.has(networkName)) { - const gateway = networkGatewayMap.get(networkName); // Handle Block Events for (const [channelId, network] of networkChannelMap) { const currBlockNum = await getCurrBlockNumber(network, channelId); diff --git a/weaver/core/drivers/fabric-driver/server/server.ts b/weaver/core/drivers/fabric-driver/server/server.ts index e6e2121690b..2730fdd142a 100644 --- a/weaver/core/drivers/fabric-driver/server/server.ts +++ b/weaver/core/drivers/fabric-driver/server/server.ts @@ -70,7 +70,7 @@ function mockCommunication(query: query_pb.Query) { const view = new state_pb.View(); view.setMeta(meta); const viewDataBinary = fabricViewPb.FabricView.deserializeBinary( - //@ts-ignore + //@ts-expect-error: should expect string mockedB64Data, ).serializeBinary(); logger.info(`viewData ${viewDataBinary}`); @@ -161,7 +161,6 @@ const spawnSubscribeEventHelper = async ( }; // Service for receiving communication from a relay. Will communicate with the network and respond with an ack to the relay while the fabric communication is being completed. -//@ts-ignore server.addService(driver_pb_grpc.DriverCommunicationService, { requestDriverState: ( call: { request: query_pb.Query }, @@ -245,8 +244,6 @@ server.addService(driver_pb_grpc.DriverCommunicationService, { call: { request: eventsPb.EventSubscription }, callback: (_: any, object: query_pb.Query) => void, ) => { - const ack_response = new ack_pb.Ack(); - signEventSubscriptionQuery(call.request.getQuery()!) .then((signedQuery) => { // gRPC response. @@ -445,11 +442,7 @@ const configSetup = async () => { `wallet-${process.env.NETWORK_NAME ? process.env.NETWORK_NAME : "network1"}`, ); if (process.env.CONNECTION_PROFILE) { - await walletSetup( - walletPath, - process.env.CONNECTION_PROFILE, - process.env.NETWORK_NAME ? process.env.NETWORK_NAME : "network1", - ); + await walletSetup(walletPath, process.env.CONNECTION_PROFILE); } else { logger.error("No CONNECTION_PROFILE provided in the .env"); } @@ -500,7 +493,7 @@ if (process.env.DRIVER_TLS === "true") { server.bindAsync( `${process.env.DRIVER_ENDPOINT}`, ServerCredentials.createSsl(null, [keyCertPair], false), - (cb) => { + () => { configSetup().then(() => { logger.info("Starting server with TLS"); monitorService(); @@ -511,7 +504,7 @@ if (process.env.DRIVER_TLS === "true") { server.bindAsync( `${process.env.DRIVER_ENDPOINT}`, ServerCredentials.createInsecure(), - (cb) => { + () => { configSetup().then(() => { logger.info("Starting server without TLS"); monitorService(); diff --git a/weaver/core/drivers/fabric-driver/server/walletSetup.ts b/weaver/core/drivers/fabric-driver/server/walletSetup.ts index aeba3ac1cb4..2f59ca3c796 100644 --- a/weaver/core/drivers/fabric-driver/server/walletSetup.ts +++ b/weaver/core/drivers/fabric-driver/server/walletSetup.ts @@ -31,7 +31,6 @@ const getConfig = () => { const walletSetup = async ( walletPath: string, conn_profile_path: string, - networkName: string, ): Promise => { const ccpPath = conn_profile_path ? path.resolve(__dirname, conn_profile_path) @@ -56,6 +55,7 @@ const walletSetup = async ( logger.debug(`CA URL ${caURL}`); const ca = new FabricCAServices(caURL); const ident = ca.newIdentityService(); + logger.debug(ident) const wallet = await Wallets.newFileSystemWallet(walletPath); const adminName = config.admin.name; diff --git a/yarn.lock b/yarn.lock index de9629c6908..dadb5758d36 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7381,6 +7381,12 @@ __metadata: languageName: unknown linkType: soft +"@hyperledger/cacti-plugin-weaver-driver-fabric@workspace:packages/cacti-plugin-weaver-driver-fabric": + version: 0.0.0-use.local + resolution: "@hyperledger/cacti-plugin-weaver-driver-fabric@workspace:packages/cacti-plugin-weaver-driver-fabric" + languageName: unknown + linkType: soft + "@hyperledger/cacti-weaver-besu-cli@workspace:weaver/samples/besu/besu-cli": version: 0.0.0-use.local resolution: "@hyperledger/cacti-weaver-besu-cli@workspace:weaver/samples/besu/besu-cli"