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(fabric-driver): added weaver fabric driver as cacti package #2963

Merged
merged 1 commit into from
Jun 19, 2024
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
76 changes: 76 additions & 0 deletions packages/cacti-plugin-weaver-driver-fabric/package.json
Original file line number Diff line number Diff line change
@@ -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": {
"build": "cd src/main/typescript && make build",
"build-image": "cd src/main/typescript && make build-image",
"build-image-local": "cd src/main/typescript && make build-image-local",
"build-local": "cd src/main/typescript && make build-local",
"clean": "cd src/main/typescript && make clean",
"clean-local": "cd src/main/typescript && make clean-local",
"publish": "cd src/main/typescript && make push-image && make push-image-latest",
"postpublish": "cd src/main/typescript && make push-image-latest",
"watch": "npm-watch"
},
"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": {}
}
15 changes: 15 additions & 0 deletions packages/cacti-plugin-weaver-driver-fabric/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!--
Copyright IBM Corp. All Rights Reserved.

SPDX-License-Identifier: CC-BY-4.0
-->
# 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/).


14 changes: 7 additions & 7 deletions weaver/core/drivers/fabric-driver/server/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,15 @@ 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,
),
);
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,
Expand Down Expand Up @@ -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}`);
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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}`);
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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 = [],
Expand Down Expand Up @@ -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 {
Expand Down
6 changes: 2 additions & 4 deletions weaver/core/drivers/fabric-driver/server/fabric-code.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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 (
Expand Down Expand Up @@ -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();
Expand Down
37 changes: 7 additions & 30 deletions weaver/core/drivers/fabric-driver/server/listener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,7 @@

import * as fabproto6 from "fabric-protos";
import { BlockDecoder } from "fabric-common/index";
import {
Gateway,
Network,
Contract,
ContractEvent,
BlockListener,
ContractListener,
BlockEvent,
ListenerOptions,
} from "fabric-network";
import { Gateway, Network, BlockListener, BlockEvent } 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";
import { lookupEventSubscriptions, readAllEventMatchers } from "./events";
Expand All @@ -24,14 +15,8 @@ import {
handlePromise,
relayCallback,
getRelayClientForEventPublish,
delay,
} from "./utils";
import {
DBConnector,
LevelDBConnector,
DBLockedError,
DBKeyNotFoundError,
} from "./dbConnector";
import { DBConnector, LevelDBConnector } from "./dbConnector";
import logger from "./logger";

const networkGatewayMap = new Map<string, Gateway>();
Expand Down Expand Up @@ -242,8 +227,7 @@ const initBlockEventListenerForChannel = async (
channelId: string,
): Promise<any> => {
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);
Expand Down Expand Up @@ -309,8 +293,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);
Expand Down Expand Up @@ -373,8 +356,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
Expand Down Expand Up @@ -411,10 +393,7 @@ const loadEventSubscriptionsFromStorage = async (
const eventMatchers = await readAllEventMatchers();
for (const eventMatcher of eventMatchers) {
try {
const listenerHandle = await registerListenerForEventSubscription(
eventMatcher,
networkName,
);
await registerListenerForEventSubscription(eventMatcher, networkName);
} catch (error) {
logger.error(
`Error: Could not start event listener for ${JSON.stringify(eventMatcher.toObject())} with error: ${error}`,
Expand Down Expand Up @@ -478,12 +457,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);
Expand Down
15 changes: 4 additions & 11 deletions weaver/core/drivers/fabric-driver/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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}`);
Expand Down Expand Up @@ -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 },
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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");
}
Expand Down Expand Up @@ -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();
Expand All @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion weaver/core/drivers/fabric-driver/server/walletSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ const getConfig = () => {
const walletSetup = async (
walletPath: string,
conn_profile_path: string,
networkName: string,
): Promise<any> => {
const ccpPath = conn_profile_path
? path.resolve(__dirname, conn_profile_path)
Expand All @@ -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;
Expand Down
6 changes: 6 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Loading