Skip to content

Commit

Permalink
feat(SATP-Hermes): gateway coordinator WIP
Browse files Browse the repository at this point in the history
Signed-off-by: Rafael Belchior <rafael.belchior@tecnico.ulisboa.pt>
  • Loading branch information
RafaelAPB authored and AndreAugusto11 committed Mar 1, 2024
1 parent 7f86bd3 commit 0aa6f76
Show file tree
Hide file tree
Showing 20 changed files with 1,041 additions and 215 deletions.

Large diffs are not rendered by default.

161 changes: 76 additions & 85 deletions packages/cactus-plugin-bungee/src/main/typescript/plugin-bungee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,10 @@ export interface IPluginBUNGEEOptions extends ICactusPluginOptions {
disableSignalHandlers?: true;
}

export class PluginBUNGEE implements
ICactusPlugin, IPluginWebService
{
export class PluginBUNGEE implements ICactusPlugin, IPluginWebService {
public static readonly CLASS_NAME = "PluginBUNGEE";
private log: Logger;

private bungeeSigner: JsObjectSigner;
private privKeyBungee: string;
private pubKeyBungee: string;
Expand All @@ -75,14 +73,14 @@ export class PluginBUNGEE implements
private ledgerAssetsKey: string[];
private ledgerStates: Map<string, State>; //Key, state
private states: State[];

public fabricApi?: FabricApi;
public fabricSigningCredential?: FabricSigningCredential;
public fabricChannelName?: string;
public fabricContractName?: string;
public fabricAssetID?: string;
public fabricAssetSize?: string;

private readonly instanceId: string;
private level: LogLevelDesc;
private endpoints: IWebServiceEndpoint[] | undefined;
Expand All @@ -91,28 +89,28 @@ export class PluginBUNGEE implements
const fnTag = `${this.className}#constructor()`;
Checks.truthy(options, `${fnTag} arg options`);
Checks.truthy(options.instanceId, `${fnTag} options.instanceId`);

this.level = options.logLevel || "INFO";
const label = this.className;
const level = this.level;
this.log = LoggerProvider.getOrCreate({ label, level });

this.instanceId = options.instanceId;

const keysRelPath ="../keys/";
const keysRelPath = "../keys/";
const pubKeyPath = path.join(__dirname, keysRelPath, "./bungee_pub.pem");
const privKeyPath = path.join(__dirname, keysRelPath, "./bungee_priv.pem");
this.pubKeyBungee = Utils.readKeyFromFile(pubKeyPath);
this.privKeyBungee = Utils.readKeyFromFile(privKeyPath);

const bungeeSignerOptions: IJsObjectSignerOptions = {
privateKey: this.privKeyBungee,
logLevel: "debug",
};
this.bungeeSigner = new JsObjectSigner(bungeeSignerOptions);

this.participant = options.participant;

this.ledgerAssetsKey = [];
this.ledgerStates = new Map<string, State>();
this.states = [];
Expand All @@ -134,7 +132,6 @@ export class PluginBUNGEE implements

public async shutdown(): Promise<void> {
this.log.info(`Shutting down ${this.className}...`);

}

public getPackageName(): string {
Expand All @@ -160,9 +157,7 @@ export class PluginBUNGEE implements
bungee: this,
});

this.endpoints = [
clientEndpoint,
];
this.endpoints = [clientEndpoint];
return this.endpoints;
}

Expand Down Expand Up @@ -200,7 +195,7 @@ export class PluginBUNGEE implements
: "1";
}

async onCreateView(request: CreateViewRequest): Promise<CreateViewResponse> {
async onCreateView(request: CreateViewRequest): Promise<CreateViewResponse> {
//const fnTag = `${this.className}#onCreateView()`;
const response = this.generateView(this.generateSnapshot());
return {
Expand All @@ -209,59 +204,64 @@ export class PluginBUNGEE implements
}

/**
*
*
* @abstract Create ledger state. Get all keys, iterate every key and get the respective transactions. For each transaction get the receipt
* */
public async generateLedgerStates(): Promise<string> {
this.log.info(`Generating ledger snapshot`);
this.log.info(`Generating ledger snapshot`);

const assetsKey = await this.getAllAssetsKey();
this.ledgerAssetsKey = assetsKey.split(",");

//For each key in ledgerAssetsKey
for(const assetKey of this.ledgerAssetsKey){
let assetValues: string[] = [];
let txWithTimeS: Transaction[] = [];
for (const assetKey of this.ledgerAssetsKey) {
const assetValues: string[] = [];
const txWithTimeS: Transaction[] = [];

this.log.info(assetKey);
this.log.info(assetKey);
const txs = await this.getAllTxByKey(assetKey);

//For each tx get receipt
for(const tx of txs){
for (const tx of txs) {
const endorsements: Proof[] = [];
const receipt = JSON.parse(await this.fabricGetTxReceiptByTxIDV1(tx.getId()));
const receipt = JSON.parse(
await this.fabricGetTxReceiptByTxIDV1(tx.getId()),
);

// Checks if tx was made by participant
if(receipt.transactionCreator.mspid != this.participant){
if (receipt.transactionCreator.mspid != this.participant) {
continue;
}

assetValues.push(JSON.parse(receipt.rwsetWriteData).Value.toString());

//Save endorsements of tx
for (const endorsement of receipt.transactionEndorsement) {
const signature64 = Buffer.from(endorsement.signature).toString('base64');
endorsements.push(new Proof(endorsement.mspid, endorsement.endorserID, signature64));
for (const endorsement of receipt.transactionEndorsement) {
const signature64 = Buffer.from(endorsement.signature).toString(
"base64",
);
endorsements.push(
new Proof(endorsement.mspid, endorsement.endorserID, signature64),
);
}
tx.defineTxProofs(endorsements);
txWithTimeS.push(tx);
}

const state = new State(assetKey, assetValues, txWithTimeS);
this.ledgerStates.set(assetKey, state);
this.states.push(state);
}

this.ledgerStates.forEach((state: State, keyId: string) => {
console.log(keyId, state);
const assetState = this.ledgerStates.get(keyId);
if(assetState != undefined) {
this.log.info(assetState);
this.log.info(JSON.parse(assetState.getStateJson()));

if (assetState != undefined) {
this.log.info(assetState);
this.log.info(JSON.parse(assetState.getStateJson()));
}
});

// TESTS ONLY -> next receive ti tf
const car2 = this.ledgerStates.get("CAR2");

Expand All @@ -270,12 +270,11 @@ export class PluginBUNGEE implements
this.tF = car2.getTimeForTxN(1);
}

return "";
return "";
}


/**
*
*
* @abstract Returns Snapshot
* */
public generateSnapshot(): Snapshot {
Expand All @@ -284,66 +283,66 @@ export class PluginBUNGEE implements
return snapshot;
}


/**
*
*
* @abstract Returns view. Generate final view with signature
*
*
* @param snapshot - Ledger Snapshot
* */
public generateView(snapshot: Snapshot): string {
const crypto = require('crypto');
const crypto = require("crypto");

this.log.warn(this.pubKeyBungee);
this.log.warn(this.privKeyBungee);
this.log.warn(this.pubKeyBungee);
this.log.warn(this.privKeyBungee);
const view = new View(this.tI, this.tF, snapshot);
const signer = crypto.createSign('SHA256');

const signer = crypto.createSign("SHA256");
signer.write(JSON.stringify(view));
signer.end();

this.log.warn(view.getViewStr());
this.log.warn(view.getViewStr());

const signature = signer.sign(this.privKeyBungee, 'base64');
const signature = signer.sign(this.privKeyBungee, "base64");

this.saveToFile(__dirname + "/../../view/signed.json", JSON.stringify(view));
this.saveToFile(
__dirname + "/../../view/signed.json",
JSON.stringify(view),
);

const signedView = {View: view, Signature: signature};
const signedView = { View: view, Signature: signature };

this.saveToFile(__dirname + "/../../view/viewFile.json", JSON.stringify(signedView, null, 2));
this.saveToFile(
__dirname + "/../../view/viewFile.json",
JSON.stringify(signedView, null, 2),
);

return JSON.stringify(signedView);
}


/**
*
*
* @abstract Returns transaction receipt.
*
*
* @param transactionId - Transaction id to return the receipt
* */
async fabricGetTxReceiptByTxIDV1(transactionId: string): Promise<string> {
const receiptLockRes = await this.fabricApi?.getTransactionReceiptByTxIDV1(
{
signingCredential: this.fabricSigningCredential,
channelName: this.fabricChannelName,
contractName: "qscc",
invocationType: FabricContractInvocationType.Call,
methodName: "GetBlockByTxID",
params: [this.fabricChannelName, transactionId],
} as FabricRunTransactionRequest,
);
const receiptLockRes = await this.fabricApi?.getTransactionReceiptByTxIDV1({
signingCredential: this.fabricSigningCredential,
channelName: this.fabricChannelName,
contractName: "qscc",
invocationType: FabricContractInvocationType.Call,
methodName: "GetBlockByTxID",
params: [this.fabricChannelName, transactionId],
} as FabricRunTransactionRequest);

return JSON.stringify(receiptLockRes?.data);
}


/**
*
*
* @abstract Returns all assets key found in the world state.
* */
async getAllAssetsKey(): Promise<string> {

const response = await this.fabricApi?.runTransactionV1({
signingCredential: this.fabricSigningCredential,
channelName: this.fabricChannelName,
Expand All @@ -353,22 +352,20 @@ export class PluginBUNGEE implements
params: [],
} as FabricRunTransactionRequest);

if (response != undefined){
if (response != undefined) {
return response.data.functionOutput;
}

return "response undefined";
}


/**
*
*
* @abstract Returns an array of all transactions for a specific key.
*
* @param key - Key used to get correspondent transactions
* */
async getAllTxByKey(key: string): Promise<Transaction[]> {

const response = await this.fabricApi?.runTransactionV1({
signingCredential: this.fabricSigningCredential,
channelName: this.fabricChannelName,
Expand All @@ -378,23 +375,20 @@ export class PluginBUNGEE implements
params: [key],
} as FabricRunTransactionRequest);

if (response != undefined){

if (response != undefined) {
return Utils.txsStringToTxs(response.data.functionOutput);
}

return [];
}


/**
*
*
* @abstract Returns all the transactions for a specific key in string format.
*
* @param key - Key (id) used to get correspondent transactions
* */
async getAllTxByKeyString(key: string): Promise<string> {

const response = await this.fabricApi?.runTransactionV1({
signingCredential: this.fabricSigningCredential,
channelName: this.fabricChannelName,
Expand All @@ -404,30 +398,27 @@ export class PluginBUNGEE implements
params: [key],
} as FabricRunTransactionRequest);

if (response != undefined){

if (response != undefined) {
return response.data.functionOutput;
}

return "";
}


/**
*
*
* @abstract Save view in json file.
*
* @param fileName - File name or path + file name
* @param data - View in a string format to write inside the json file
* */
public saveToFile(fileName: string, data: string): void {
const fs = require("fs");

fs.writeFileSync(fileName, data, function (err: boolean) {
if (err) {
return console.log("error");
}
});
}
}

14 changes: 5 additions & 9 deletions packages/cactus-plugin-bungee/src/main/typescript/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,10 @@ import { IPluginFactoryOptions } from "@hyperledger/cactus-core-api";
import { PluginFactoryBUNGEE } from "./plugin-factory-bungee";
import * as OpenApiJson from "../json/openapi.json";

export {
PluginBUNGEE,
IPluginBUNGEEOptions,
} from "./plugin-bungee";
export { PluginBUNGEE, IPluginBUNGEEOptions } from "./plugin-bungee";

export async function createPluginFactory(
pluginFactoryOptions: IPluginFactoryOptions,
): Promise<PluginFactoryBUNGEE> {
return new PluginFactoryBUNGEE(pluginFactoryOptions);
}

pluginFactoryOptions: IPluginFactoryOptions,
): Promise<PluginFactoryBUNGEE> {
return new PluginFactoryBUNGEE(pluginFactoryOptions);
}
Loading

0 comments on commit 0aa6f76

Please sign in to comment.