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(bungee-hermes): add BUNGEE package #3640

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion packages/cactus-plugin-bungee-hermes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,4 +226,4 @@ We welcome contributions to Hyperledger Cactus in many forms, and there’s alwa
Please review [CONTRIBUTING.md](https://github.com/hyperledger/cactus/blob/main/CONTRIBUTING.md "CONTRIBUTING.md") to get started.

## License
This distribution is published under the Apache License Version 2.0 found in the [LICENSE ](https://github.com/hyperledger/cactus/blob/main/LICENSE "LICENSE ")file.
This distribution is published under the Apache License Version 2.0 found in the [LICENSE ](https://github.com/hyperledger/cactus/blob/main/LICENSE "LICENSE ")file.
1 change: 1 addition & 0 deletions packages/cactus-plugin-bungee-hermes/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"http-errors-enhanced-cjs": "2.0.1",
"key-encoder": "2.0.3",
"merkletreejs": "0.3.11",
"safe-stable-stringify": "2.5.0",
"typescript-optional": "2.0.1",
"uuid": "10.0.0",
"web3": "1.6.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
"PrivacyPolicyOpts": {
"description": "identifier of the policy used to process a view",
"type": "string",
"enum": ["pruneState"],
"x-enum-varnames": ["PruneState"]
"enum": ["pruneState", "singleTransaction"],
"x-enum-varnames": ["PruneState", "SingleTransaction"]
},
"MergePolicyOpts": {
"description": "identifier of the policy used to merge views (can be none)",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
"PrivacyPolicyOpts": {
"description": "identifier of the policy used to process a view",
"type": "string",
"enum": ["pruneState"],
"x-enum-varnames": ["PruneState"]
"enum": ["pruneState", "singleTransaction"],
"x-enum-varnames": ["PruneState", "SingleTransaction"]
},
"MergePolicyOpts": {
"description": "identifier of the policy used to merge views (can be none)",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,8 @@ export interface MergeViewsResponse {
*/

export const PrivacyPolicyOpts = {
PruneState: 'pruneState'
PruneState: 'pruneState',
SingleTransaction: 'singleTransaction'
} as const;

export type PrivacyPolicyOpts = typeof PrivacyPolicyOpts[keyof typeof PrivacyPolicyOpts];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
LoggerProvider,
Secp256k1Keys,
} from "@hyperledger/cactus-common";
import { stringify as safeStableStringify } from "safe-stable-stringify";

import { v4 as uuidV4 } from "uuid";
import {
ICactusPlugin,
Expand Down Expand Up @@ -231,8 +233,8 @@ export class PluginBungeeHermes implements ICactusPlugin, IPluginWebService {
view.setCreator(this.pubKeyBungee);
view.setKey(uuidV4());
return {
view: JSON.stringify(view),
signature: this.sign(JSON.stringify(view)),
view: safeStableStringify(view),
signature: this.sign(safeStableStringify(view)),
};
}
onMergeViews(request: MergeViewsRequest): MergeViewsResponse {
Expand Down Expand Up @@ -267,7 +269,7 @@ export class PluginBungeeHermes implements ICactusPlugin, IPluginWebService {
request.policyArguments ? request.policyArguments : [],
);
return {
integratedView: JSON.stringify(integratedView),
integratedView: safeStableStringify(integratedView),
signature: integratedView.signature,
};
}
Expand All @@ -287,7 +289,7 @@ export class PluginBungeeHermes implements ICactusPlugin, IPluginWebService {
this.logger.info("Generating view for request: ", request);
const response = this.generateView(snapshot, ti, tf, request.viewID);
return {
view: JSON.stringify(response.view),
view: safeStableStringify(response.view),
signature: response.signature,
};
}
Expand All @@ -308,7 +310,7 @@ export class PluginBungeeHermes implements ICactusPlugin, IPluginWebService {
const view = new View(this.pubKeyBungee, tI, tF, snapshot, id);
snapshot.pruneStates(tI, tF);

const signature = this.sign(JSON.stringify(view));
const signature = this.sign(safeStableStringify(view));

return { view: view, signature: signature };
}
Expand Down Expand Up @@ -414,7 +416,7 @@ export class PluginBungeeHermes implements ICactusPlugin, IPluginWebService {
integratedView: integratedView,
//The paper specs suggest the integratedView should be jointly signed by all participants.
//That process is left to be addressed in the future
signature: this.sign(JSON.stringify(integratedView)),
signature: this.sign(safeStableStringify(integratedView)),
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { IPluginFactoryOptions } from "@hyperledger/cactus-core-api";
import { PluginFactoryBungeeHermes } from "./plugin-factory-bungee-hermes";

export { isMergePolicyValueArray } from "./view-merging/merge-policies";
export { isPrivacyPolicyValueArray } from "./view-creation/privacy-policies";

export {
PluginBungeeHermes,
IPluginBungeeHermesOptions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
Logger,
LoggerProvider,
} from "@hyperledger/cactus-common";
import { stringify as safeStableStringify } from "safe-stable-stringify";

import {
DefaultApi as BesuApi,
EthContractInvocationType,
Expand Down Expand Up @@ -170,7 +172,7 @@ export class StrategyBesu implements ObtainLedgerStrategy {
"Transaction: " +
log.transactionHash +
"\nData: " +
JSON.stringify(log.data) +
safeStableStringify(log.data) +
"\n =========== \n",
);
const proof = new Proof({
Expand All @@ -185,7 +187,7 @@ export class StrategyBesu implements ObtainLedgerStrategy {
transaction.setTarget(networkDetails.contractAddress as string);
transaction.setPayload(txTx.input ? txTx.input : ""); //FIXME: payload = transaction input ?
transactions.push(transaction);
values.push(JSON.stringify(log.data));
values.push(safeStableStringify(log.data));

blocks.set(transaction.getId(), txBlock);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import {
LoggerProvider,
Checks,
} from "@hyperledger/cactus-common";
import { stringify as safeStableStringify } from "safe-stable-stringify";

import {
Web3SigningCredential,
DefaultApi as EthereumApi,
Expand Down Expand Up @@ -214,7 +216,7 @@ export class StrategyEthereum implements ObtainLedgerStrategy {
"Transaction: " +
log.transactionHash +
"\nData: " +
JSON.stringify(log.data) +
safeStableStringify(log.data) +
"\n =========== \n",
);
const proof = new Proof({
Expand All @@ -229,7 +231,7 @@ export class StrategyEthereum implements ObtainLedgerStrategy {
transaction.setTarget(networkDetails.contractAddress as string);
transaction.setPayload(txTx.data.input ? txTx.data.input : ""); //FIXME: payload = transaction input ?
transactions.push(transaction);
values.push(JSON.stringify(log.data));
values.push(safeStableStringify(log.data));

blocks.set(transaction.getId(), txBlock.data);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
Logger,
LoggerProvider,
} from "@hyperledger/cactus-common";
import { stringify as safeStableStringify } from "safe-stable-stringify";
import { Transaction } from "../view-creation/transaction";
import { State } from "../view-creation/state";
import { StateProof } from "../view-creation/state-proof";
Expand Down Expand Up @@ -101,7 +102,11 @@ export class StrategyFabric implements ObtainLedgerStrategy {
mspid: receipt.transactionCreator.mspid,
}),
);
assetValues.push(JSON.parse(receipt.rwsetWriteData).Value.toString());
if (!receipt.rwsetWriteData) {
assetValues.push("");
} else {
assetValues.push(JSON.parse(receipt.rwsetWriteData).Value.toString());
}
tx.setStateId(assetKey);
tx.setTarget(receipt.channelID + ": " + receipt.chainCodeName);

Expand Down Expand Up @@ -135,10 +140,11 @@ export class StrategyFabric implements ObtainLedgerStrategy {
//only adding last block for each state, in the state proof
stateProof.addBlock({
blockHash: block.hash,
blockCreator: JSON.stringify({
mspid: last_receipt.blockMetaData.mspid,
id: last_receipt.blockMetaData.blockCreatorID,
}),
blockCreator:
safeStableStringify({
mspid: last_receipt.blockMetaData.mspid,
id: last_receipt.blockMetaData.blockCreatorID,
}) ?? "",
blockSigners: block.signers,
});

Expand Down Expand Up @@ -170,7 +176,7 @@ export class StrategyFabric implements ObtainLedgerStrategy {
if (!response) {
throw new InternalServerError(`${fn} response is falsy`);
}
const receiptLockRes = JSON.stringify(response);
const receiptLockRes = safeStableStringify(response);
if (!receiptLockRes) {
throw new InternalServerError(`${fn} receiptLockRes is falsy`);
}
Expand Down Expand Up @@ -199,7 +205,7 @@ export class StrategyFabric implements ObtainLedgerStrategy {
throw new InternalServerError(`${fn} response.data is falsy`);
}

const receiptLockRes = JSON.stringify(data);
const receiptLockRes = safeStableStringify(data);
if (!receiptLockRes) {
throw new InternalServerError(`${fn} receiptLockRes is falsy`);
}
Expand Down Expand Up @@ -275,7 +281,7 @@ export class StrategyFabric implements ObtainLedgerStrategy {
);
}

const block = JSON.parse(JSON.stringify(block_data)).decodedBlock;
const block = JSON.parse(safeStableStringify(block_data)).decodedBlock;

const blockSig = block.metadata.metadata[0].signatures;
const sigs = [];
Expand All @@ -289,7 +295,7 @@ export class StrategyFabric implements ObtainLedgerStrategy {
},
signature: Buffer.from(sig.signature.data).toString("hex"),
};
sigs.push(JSON.stringify(decoded));
sigs.push(safeStableStringify(decoded));
}
return {
hash: Buffer.from(block.header.data_hash.data).toString("hex"),
Expand Down Expand Up @@ -440,7 +446,7 @@ export class StrategyFabric implements ObtainLedgerStrategy {
ts,
new TransactionProof(new Proof({ creator: "" }), txId), //transaction proof details are set in function 'generateLedgerStates'
);
transaction.setPayload(JSON.stringify(tx.value));
transaction.setPayload(safeStableStringify(tx.value) ?? "");
transactions.push(transaction);
}
return transactions.reverse();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,35 @@ export interface IPrivacyPolicyValue {
policy: PrivacyPolicyOpts;
policyHash: string;
}

// Type guard for PrivacyPolicyOpts
export function isPrivacyPolicyOpts(
value: unknown,
): value is PrivacyPolicyOpts {
return (
typeof value === "string" &&
Object.values(PrivacyPolicyOpts).includes(value as PrivacyPolicyOpts)
);
}

// Type guard for IPrivacyPolicyValue
export function isPrivacyPolicyValue(obj: unknown): obj is IPrivacyPolicyValue {
return (
typeof obj === "object" &&
obj !== null &&
"policy" in obj && // Ensure 'policy' key exists
isPrivacyPolicyOpts((obj as Record<string, unknown>).policy) && // Check if policy is a valid PrivacyPolicyOpts value
typeof (obj as Record<string, unknown>).policyHash === "string" // Ensure 'policyHash' is a string
);
}

// Type guard for an array of IPrivacyPolicyValue
export function isPrivacyPolicyValueArray(
input: unknown,
): input is Array<IPrivacyPolicyValue> {
return Array.isArray(input) && input.every(isPrivacyPolicyValue);
}

export class PrivacyPolicies {
constructor() {}

Expand All @@ -18,11 +47,24 @@ export class PrivacyPolicies {
return view;
}

public singleTransaction(
view: View,
stateId: string,
transactionId: string,
): View {
const snapshot = view.getSnapshot();
snapshot.filterTransaction(stateId, transactionId);
return view;
}

public getPrivacyPolicy(opts: PrivacyPolicyOpts): IPrivacyPolicy | undefined {
switch (opts) {
case PrivacyPolicyOpts.PruneState:
return this.pruneState;
break;
case PrivacyPolicyOpts.SingleTransaction:
return this.singleTransaction;
break;
default:
return undefined;
break;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Proof is a general purpose type, used to represent signatures of diverse elements.
// Proof may be used, for example in Fabric, to represent an transaction endorsement
// Or simply the signature of a transaction upon is creation (in Besu)
import { stringify as safeStableStringify } from "safe-stable-stringify";

export class Proof {
// The term creator refers to the ID of the entity who created the signature
// For example endorserID in Fabric (when Proof represents an endorsement)
Expand Down Expand Up @@ -36,7 +38,7 @@ export class Proof {
mspid: this.mspid,
signature: this.signature,
};
return JSON.stringify(proof);
return safeStableStringify(proof);
}

public getCreator(): string {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { State } from "./state";
import { stringify as safeStableStringify } from "safe-stable-stringify";

export class Snapshot {
private id: string;
Expand Down Expand Up @@ -76,14 +77,30 @@ export class Snapshot {
this.stateBins = stateBins;
}

public selectStates(states: string[]): void {
const stateBins: State[] = [];
for (const state of this.stateBins) {
if (states.includes(state.getId())) {
stateBins.push(state);
}
}
this.stateBins = stateBins;
}

public filterTransaction(stateId: string, transaction: string): void {
this.selectStates([stateId]);
const state = this.stateBins[0];
state.selectTransactions([transaction]);
}

public getSnapshotJson(): string {
const snapshotJson = {
id: this.id,
participant: this.participant,
stateBins: this.stateBins,
};

return JSON.stringify(snapshotJson);
return safeStableStringify(snapshotJson);
}

public removeState(stateId: string) {
Expand Down
Loading
Loading