Skip to content

Commit

Permalink
update apply operations
Browse files Browse the repository at this point in the history
  • Loading branch information
trungnotchung committed Dec 31, 2024
1 parent bfda6d6 commit 1ac2afe
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 13 deletions.
47 changes: 35 additions & 12 deletions packages/object/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,27 +102,32 @@ export class DRPObject implements IDRPObject {
}

// This function is black magic, it allows us to intercept calls to the DRP object
proxyDRPHandler(): ProxyHandler<object> {
proxyDRPHandler(parentProp?: string): ProxyHandler<object> {
const obj = this;
return {
get(target, propKey, receiver) {
const value = Reflect.get(target, propKey, receiver);

if (typeof value === "function") {
const fullPropKey = parentProp
? `${parentProp}.${String(propKey)}`
: String(propKey);
return new Proxy(target[propKey as keyof object], {
apply(applyTarget, thisArg, args) {
if ((thisArg.operations as string[]).includes(propKey as string))
obj.callFn(
propKey as string,
args.length === 1 ? args[0] : args,
);
obj.callFn(fullPropKey, args.length === 1 ? args[0] : args);
return Reflect.apply(applyTarget, thisArg, args);
},
});
}

if (propKey === "acl" && typeof value === "object" && value !== null) {
return new Proxy(value, this);
return new Proxy(
value,
obj.proxyDRPHandler(
parentProp ? `${parentProp}.${String(propKey)}` : String(propKey),
),
);
}

return value;
Expand Down Expand Up @@ -191,6 +196,28 @@ export class DRPObject implements IDRPObject {
}
}

private _applyOperation(drp: DRP, operation: Operation) {
const { type, value } = operation;

const typeParts = type.split(".");
// biome-ignore lint: target can be anything
let target: any = drp;
for (let i = 0; i < typeParts.length - 1; i++) {
target = target[typeParts[i]];
if (!target) {
throw new Error(`Invalid operation type: ${type}`);
}
}

const methodName = typeParts[typeParts.length - 1];
if (typeof target[methodName] !== "function") {
throw new Error(`${type} is not a function`);
}

const args = Array.isArray(value) ? value : [value];
target[methodName](...args);
}

private _computeState(
vertexDependencies: Hash[],
vertexOperation?: Operation | undefined,
Expand Down Expand Up @@ -223,14 +250,10 @@ export class DRPObject implements IDRPObject {
}

for (const op of linearizedOperations) {
const args = Array.isArray(op.value) ? op.value : [op.value];
drp[op.type](...args);
this._applyOperation(drp, op);
}
if (vertexOperation) {
const args = Array.isArray(vertexOperation.value)
? vertexOperation.value
: [vertexOperation.value];
drp[vertexOperation.type](...args);
this._applyOperation(drp, vertexOperation);
}

const varNames: string[] = Object.keys(drp);
Expand Down
33 changes: 32 additions & 1 deletion packages/object/tests/hashgraph.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { beforeEach, describe, expect, test } from "vitest";
import { AddWinsSet } from "../../blueprints/src/AddWinsSet/index.js";
import { PseudoRandomWinsSet } from "../../blueprints/src/PseudoRandomWinsSet/index.js";
import { DRPObject, type Operation, OperationType } from "../src/index.js";
import { AddWinsSetWithACL } from "@topology-foundation/blueprints/src/AddWinsSetWithACL/index.js";

describe("HashGraph construction tests", () => {
let obj1: DRPObject;
Expand Down Expand Up @@ -633,3 +633,34 @@ describe("Vertex timestamp tests", () => {
).toThrowError("Invalid timestamp detected.");
});
});

describe("Operation with ACL tests", () => {
let obj1: DRPObject;
let obj2: DRPObject;

beforeEach(async () => {
const peerIdToPublicKey = new Map<string, string>([
["peer1", "publicKey1"],
]);
obj1 = new DRPObject(
"peer1",
new AddWinsSetWithACL<number>(peerIdToPublicKey),
);
obj2 = new DRPObject(
"peer2",
new AddWinsSetWithACL<number>(peerIdToPublicKey),
);
});

test("Node with admin permission can grant permission to other nodes", () => {
/*
ROOT -- V1:GRANT("peer2")
*/

const drp1 = obj1.drp as AddWinsSetWithACL<number>;
const drp2 = obj2.drp as AddWinsSetWithACL<number>;
drp1.acl.grant("peer1", "peer2", "publicKey2");
obj2.merge(obj1.hashGraph.getAllVertices());
expect(drp2.acl.isWriter("peer2")).toBe(true);
});
});

0 comments on commit 1ac2afe

Please sign in to comment.