Skip to content

Commit

Permalink
feat(plugin-satp-hermes): replace IPFS dependency in SATP package
Browse files Browse the repository at this point in the history
* implement the repository design pattern to make storage technology agnostic
* due to the deprecation of the ipfs package, this allows one to choose another storage
* refactoring of the tests and the CBDC example that is based on the SATP
* implement the remote log storage as a sqlite database
* add post build instruction to copy knex files to dist/

closes hyperledger#2984

Signed-off-by: André Augusto <andre.augusto@tecnico.ulisboa.pt>
  • Loading branch information
AndreAugusto11 committed Feb 7, 2024
1 parent 4184cf2 commit 6aeae6f
Show file tree
Hide file tree
Showing 69 changed files with 1,373 additions and 2,302 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,13 @@ import {
} from "@hyperledger/cactus-cmd-api-server";
import {
Configuration,
DefaultApi as OdapApi,
IKeyPair,
} from "@hyperledger/cactus-plugin-satp-hermes";
DefaultApi as SatpApi,
} from "@hyperledger/cactus-plugin-satp-hermes/";
import { PluginKeychainMemory } from "@hyperledger/cactus-plugin-keychain-memory";
import { CbdcBridgingAppDummyInfrastructure } from "./infrastructure/cbdc-bridging-app-dummy-infrastructure";
import { DefaultApi as FabricApi } from "@hyperledger/cactus-plugin-ledger-connector-fabric";
import { DefaultApi as BesuApi } from "@hyperledger/cactus-plugin-ledger-connector-besu";
import { DefaultApi as IpfsApi } from "@hyperledger/cactus-plugin-object-store-ipfs";
import { FabricSatpGateway } from "./satp-extension/fabric-satp-gateway";
import { BesuSatpGateway } from "./satp-extension/besu-satp-gateway";
import CryptoMaterial from "../../crypto-material/crypto-material.json";
Expand Down Expand Up @@ -81,8 +80,6 @@ export class CbdcBridgingApp {
const fabricPlugin =
await this.infrastructure.createFabricLedgerConnector();
const besuPlugin = await this.infrastructure.createBesuLedgerConnector();
const clientIpfsPlugin = await this.infrastructure.createIPFSConnector();
const serverIpfsPlugin = await this.infrastructure.createIPFSConnector();

// Reserve the ports where the API Servers will run
const httpApiA = await Servers.startOnPort(
Expand All @@ -100,16 +97,14 @@ export class CbdcBridgingApp {
const addressInfoB = httpApiB.address() as AddressInfo;
const nodeApiHostB = `http://${this.options.apiHost}:${addressInfoB.port}`;

const fabricOdapGateway = await this.infrastructure.createClientGateway(
const fabricSatpGateway = await this.infrastructure.createClientGateway(
nodeApiHostA,
this.options.clientGatewayKeyPair,
`http://${this.options.apiHost}:${addressInfoA.port}`,
);

const besuOdapGateway = await this.infrastructure.createServerGateway(
const besuSatpGateway = await this.infrastructure.createServerGateway(
nodeApiHostB,
this.options.serverGatewayKeyPair,
`http://${this.options.apiHost}:${addressInfoB.port}`,
);

const clientPluginRegistry = new PluginRegistry({
Expand All @@ -132,12 +127,10 @@ export class CbdcBridgingApp {
});

clientPluginRegistry.add(fabricPlugin);
clientPluginRegistry.add(fabricOdapGateway);
clientPluginRegistry.add(clientIpfsPlugin);
clientPluginRegistry.add(fabricSatpGateway);

serverPluginRegistry.add(besuPlugin);
serverPluginRegistry.add(serverIpfsPlugin);
serverPluginRegistry.add(besuOdapGateway);
serverPluginRegistry.add(besuSatpGateway);

const apiServer1 = await this.startNode(httpApiA, clientPluginRegistry);
const apiServer2 = await this.startNode(httpApiB, serverPluginRegistry);
Expand Down Expand Up @@ -165,17 +158,16 @@ export class CbdcBridgingApp {
return {
apiServer1,
apiServer2,
fabricGatewayApi: new OdapApi(
fabricGatewayApi: new SatpApi(
new Configuration({ basePath: nodeApiHostA }),
),
besuGatewayApi: new OdapApi(
besuGatewayApi: new SatpApi(
new Configuration({ basePath: nodeApiHostB }),
),
ipfsApiClient: new IpfsApi(new Configuration({ basePath: nodeApiHostA })),
fabricApiClient,
besuApiClient,
fabricOdapGateway,
besuOdapGateway,
fabricSatpGateway,
besuSatpGateway,
};
}

Expand Down Expand Up @@ -231,11 +223,10 @@ export class CbdcBridgingApp {
export interface IStartInfo {
readonly apiServer1: ApiServer;
readonly apiServer2: ApiServer;
readonly fabricGatewayApi: OdapApi;
readonly besuGatewayApi: OdapApi;
readonly ipfsApiClient: IpfsApi;
readonly fabricGatewayApi: SatpApi;
readonly besuGatewayApi: SatpApi;
readonly besuApiClient: BesuApi;
readonly fabricApiClient: FabricApi;
readonly fabricOdapGateway: FabricSatpGateway;
readonly besuOdapGateway: BesuSatpGateway;
readonly fabricSatpGateway: FabricSatpGateway;
readonly besuSatpGateway: BesuSatpGateway;
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
DEFAULT_FABRIC_2_AIO_IMAGE_NAME,
DEFAULT_FABRIC_2_AIO_IMAGE_VERSION,
FabricTestLedgerV1,
GoIpfsTestContainer,
} from "@hyperledger/cactus-test-tooling";
import { PluginKeychainMemory } from "@hyperledger/cactus-plugin-keychain-memory";
import {
Expand All @@ -35,14 +34,15 @@ import {
InvokeContractV1Request as BesuInvokeContractV1Request,
} from "@hyperledger/cactus-plugin-ledger-connector-besu";
import { PluginRegistry } from "@hyperledger/cactus-core";
import { PluginObjectStoreIpfs } from "@hyperledger/cactus-plugin-object-store-ipfs";
import AssetReferenceContractJson from "../../../solidity/asset-reference-contract/AssetReferenceContract.json";
import CBDCcontractJson from "../../../solidity/cbdc-erc-20/CBDCcontract.json";
import { IKeyPair } from "@hyperledger/cactus-plugin-satp-hermes";
import { FabricSatpGateway } from "../satp-extension/fabric-satp-gateway";
import { BesuSatpGateway } from "../satp-extension/besu-satp-gateway";
import { PluginImportType } from "@hyperledger/cactus-core-api";
import CryptoMaterial from "../../../crypto-material/crypto-material.json";
import { ClientHelper } from "../satp-extension/client-helper";
import { ServerHelper } from "../satp-extension/server-helper";

export interface ICbdcBridgingAppDummyInfrastructureOptions {
logLevel?: LogLevelDesc;
Expand All @@ -56,9 +56,6 @@ export class CbdcBridgingAppDummyInfrastructure {

private readonly besu: BesuTestLedger;
private readonly fabric: FabricTestLedgerV1;
private readonly ipfs: GoIpfsTestContainer;
private readonly ipfsParentPath: string;

private readonly log: Logger;

public get className(): string {
Expand All @@ -78,8 +75,6 @@ export class CbdcBridgingAppDummyInfrastructure {
const level = this.options.logLevel || "INFO";
const label = this.className;

this.ipfsParentPath = `/${uuidv4()}/${uuidv4()}/`;

this.log = LoggerProvider.getOrCreate({ level, label });

this.besu = new BesuTestLedger({
Expand All @@ -97,10 +92,6 @@ export class CbdcBridgingAppDummyInfrastructure {
]),
logLevel: level || "DEBUG",
});

this.ipfs = new GoIpfsTestContainer({
logLevel: level || "DEBUG",
});
}

public get org1Env(): NodeJS.ProcessEnv & DeploymentTargetOrgFabric2x {
Expand Down Expand Up @@ -140,11 +131,7 @@ export class CbdcBridgingAppDummyInfrastructure {
public async start(): Promise<void> {
try {
this.log.info(`Starting dummy infrastructure...`);
await Promise.all([
this.besu.start(),
this.fabric.start(),
this.ipfs.start(),
]);
await Promise.all([this.besu.start(), this.fabric.start()]);
this.log.info(`Started dummy infrastructure OK`);
} catch (ex) {
this.log.error(`Starting of dummy infrastructure crashed: `, ex);
Expand All @@ -158,7 +145,6 @@ export class CbdcBridgingAppDummyInfrastructure {
await Promise.all([
this.besu.stop().then(() => this.besu.destroy()),
this.fabric.stop().then(() => this.fabric.destroy()),
this.ipfs.stop().then(() => this.ipfs.destroy()),
]);
this.log.info(`Stopped OK`);
} catch (ex) {
Expand Down Expand Up @@ -285,61 +271,43 @@ export class CbdcBridgingAppDummyInfrastructure {
return besuConnector;
}

public async createIPFSConnector(): Promise<PluginObjectStoreIpfs> {
this.log.info(`Creating Besu Connector...`);

const kuboRpcClientModule = await import("kubo-rpc-client");
const ipfsClientOrOptions = kuboRpcClientModule.create({
url: await this.ipfs.getApiUrl(),
});

return new PluginObjectStoreIpfs({
parentDir: this.ipfsParentPath,
logLevel: this.options.logLevel,
instanceId: uuidv4(),
ipfsClientOrOptions,
});
}

public async createClientGateway(
nodeApiHost: string,
keyPair: IKeyPair,
ipfsPath: string,
): Promise<FabricSatpGateway> {
this.log.info(`Creating Source Gateway...`);
const pluginSourceGateway = new FabricSatpGateway({
name: "cactus-plugin-source#satpGateway",
dltIDs: ["DLT2"],
instanceId: uuidv4(),
keyPair: keyPair,
ipfsPath: ipfsPath,
fabricPath: nodeApiHost,
fabricSigningCredential: {
keychainId: CryptoMaterial.keychains.keychain1.id,
keychainRef: "bridge",
},
fabricChannelName: "mychannel",
fabricContractName: "asset-reference-contract",
clientHelper: new ClientHelper(),
serverHelper: new ServerHelper({}),
});

await pluginSourceGateway.database?.migrate.rollback();
await pluginSourceGateway.database?.migrate.latest();
await pluginSourceGateway.localRepository?.reset();
await pluginSourceGateway.remoteRepository?.reset();

return pluginSourceGateway;
}

public async createServerGateway(
nodeApiHost: string,
keyPair: IKeyPair,
ipfsPath: string,
): Promise<BesuSatpGateway> {
this.log.info(`Creating Recipient Gateway...`);
const pluginRecipientGateway = new BesuSatpGateway({
name: "cactus-plugin-recipient#satpGateway",
dltIDs: ["DLT1"],
instanceId: uuidv4(),
keyPair: keyPair,
ipfsPath: ipfsPath,
besuPath: nodeApiHost,
besuWeb3SigningCredential: {
ethAccount: CryptoMaterial.accounts["bridge"].ethAddress,
Expand All @@ -348,10 +316,12 @@ export class CbdcBridgingAppDummyInfrastructure {
},
besuContractName: AssetReferenceContractJson.contractName,
besuKeychainId: CryptoMaterial.keychains.keychain2.id,
clientHelper: new ClientHelper(),
serverHelper: new ServerHelper({}),
});

await pluginRecipientGateway.database?.migrate.rollback();
await pluginRecipientGateway.database?.migrate.latest();
await pluginRecipientGateway.localRepository?.reset();
await pluginRecipientGateway.remoteRepository?.reset();

return pluginRecipientGateway;
}
Expand Down Expand Up @@ -624,19 +594,28 @@ export class CbdcBridgingAppDummyInfrastructure {
// does the same thing, it just waits 10 seconds for good measure so there
// might not be a way for us to avoid doing this, but if there is a way we
// absolutely should not have timeouts like this, anywhere...
await new Promise((resolve) => setTimeout(resolve, 10000));

await fabricApiClient.runTransactionV1({
contractName,
channelName,
params: ["name1", "symbol1", "8"],
methodName: "Initialize",
invocationType: FabricContractInvocationType.Send,
signingCredential: {
keychainId: CryptoMaterial.keychains.keychain1.id,
keychainRef: "userA",
},
});
let retries_2 = 0;
while (retries_2 <= 5) {
await new Promise((resolve) => setTimeout(resolve, 10000));

await fabricApiClient
.runTransactionV1({
contractName,
channelName,
params: ["name1", "symbol1", "8"],
methodName: "Initialize",
invocationType: FabricContractInvocationType.Send,
signingCredential: {
keychainId: CryptoMaterial.keychains.keychain1.id,
keychainRef: "userA",
},
})
.then(() => (retries_2 = 6))
.catch(() =>
console.log("trying to Initialize fabric contract again"),
);
retries_2++;
}
})
.catch(() => console.log("trying to deploy fabric contract again"));
retries++;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { Knex } from "knex";
import { Configuration } from "@hyperledger/cactus-core-api";
import {
DefaultApi as BesuApi,
Expand All @@ -8,32 +7,18 @@ import {
InvokeContractV1Request as BesuInvokeContractV1Request,
} from "@hyperledger/cactus-plugin-ledger-connector-besu";
import {
IKeyPair,
IPluginSatpGatewayConstructorOptions,
PluginSatpGateway,
} from "@hyperledger/cactus-plugin-satp-hermes";
import { SessionDataRollbackActionsPerformedEnum } from "@hyperledger/cactus-plugin-satp-hermes";
import { ClientHelper } from "./client-helper";
import { ServerHelper } from "./server-helper";

export interface IBesuSatpGatewayConstructorOptions {
name: string;
dltIDs: string[];
instanceId: string;
keyPair?: IKeyPair;
backupGatewaysAllowed?: string[];

ipfsPath?: string;

besuPath?: string;

export interface IBesuSatpGatewayConstructorOptions
extends IPluginSatpGatewayConstructorOptions {
besuContractName?: string;
besuWeb3SigningCredential?: Web3SigningCredential;
besuKeychainId?: string;
fabricAssetID?: string;
fabricAssetSize?: string;
besuAssetID?: string;

knexConfig?: Knex.Config;
besuPath?: string;
}

export class BesuSatpGateway extends PluginSatpGateway {
Expand All @@ -50,8 +35,10 @@ export class BesuSatpGateway extends PluginSatpGateway {
keyPair: options.keyPair,
backupGatewaysAllowed: options.backupGatewaysAllowed,
ipfsPath: options.ipfsPath,
clientHelper: new ClientHelper(),
serverHelper: new ServerHelper({}),
clientHelper: options.clientHelper,
serverHelper: options.serverHelper,
knexLocalConfig: options.knexLocalConfig,
knexRemoteConfig: options.knexRemoteConfig,
});

if (options.besuPath != undefined) this.defineBesuConnection(options);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
TransferInitializationV1Request,
ClientGatewayHelper,
} from "@hyperledger/cactus-plugin-satp-hermes";
import { OdapMessageType } from "@hyperledger/cactus-plugin-satp-hermes";
import { SatpMessageType } from "@hyperledger/cactus-plugin-satp-hermes";
import { FabricSatpGateway } from "./fabric-satp-gateway";
import { BesuSatpGateway } from "./besu-satp-gateway";

Expand Down Expand Up @@ -44,14 +44,16 @@ export class ClientHelper extends ClientGatewayHelper {
throw new Error(`${fnTag}, session data is not correctly initialized`);
}

if (!gateway.supportedDltIDs.includes(sessionData.recipientGatewayDltSystem)) {
if (
!gateway.supportedDltIDs.includes(sessionData.recipientGatewayDltSystem)
) {
throw new Error(
`${fnTag}, recipient gateway dlt system is not supported by this gateway`,
);
}

const initializationRequestMessage: TransferInitializationV1Request = {
messageType: OdapMessageType.InitializationRequest,
messageType: SatpMessageType.InitializationRequest,
sessionID: sessionData.id,
version: sessionData.version,
// developer urn
Expand Down Expand Up @@ -132,7 +134,7 @@ export class ClientHelper extends ClientGatewayHelper {

await gateway.makeRequest(
sessionID,
PluginSatpGateway.getOdapAPI(
PluginSatpGateway.getSatpAPI(
sessionData.recipientBasePath,
).phase1TransferInitiationRequestV1(initializationRequestMessage),
"TransferInitializationRequest",
Expand Down
Loading

0 comments on commit 6aeae6f

Please sign in to comment.