diff --git a/packages/node/src/handlers.ts b/packages/node/src/handlers.ts index 560d87fb..744d981e 100644 --- a/packages/node/src/handlers.ts +++ b/packages/node/src/handlers.ts @@ -32,7 +32,7 @@ export async function topologyMessagesHandler( switch (message.type) { case NetworkPb.Message_MessageType.UPDATE: - updateHandler(node, message.data); + updateHandler(node, message.data, message.sender); break; case NetworkPb.Message_MessageType.SYNC: if (!stream) { @@ -71,7 +71,11 @@ export async function topologyMessagesHandler( data: { id: string, operations: {nonce: string, fn: string, args: string[] }[] } operations array doesn't contain the full remote operations array */ -function updateHandler(node: TopologyNode, data: Uint8Array) { +async function updateHandler( + node: TopologyNode, + data: Uint8Array, + sender: string, +) { const updateMessage = NetworkPb.Update.decode(data); const object = node.objectStore.get(updateMessage.objectId); if (!object) { @@ -79,7 +83,7 @@ function updateHandler(node: TopologyNode, data: Uint8Array) { return false; } - object.merge( + const [merged, _] = object.merge( updateMessage.vertices.map((v) => { return { hash: v.hash, @@ -92,6 +96,11 @@ function updateHandler(node: TopologyNode, data: Uint8Array) { }; }), ); + + if (!merged) { + await node.syncObject(updateMessage.objectId, sender); + } + node.objectStore.put(object.id, object); return true; diff --git a/packages/node/src/version.ts b/packages/node/src/version.ts index 387b59eb..767a57d4 100644 --- a/packages/node/src/version.ts +++ b/packages/node/src/version.ts @@ -1 +1 @@ -export const VERSION = "0.3.0"; +export const VERSION = "0.3.1"; diff --git a/packages/object/src/hashgraph/index.ts b/packages/object/src/hashgraph/index.ts index ba269009..93539c7f 100644 --- a/packages/object/src/hashgraph/index.ts +++ b/packages/object/src/hashgraph/index.ts @@ -118,18 +118,20 @@ export class HashGraph { return vertex; } + /* Add a vertex to the hashgraph with the given operation and dependencies. + * If the vertex already exists, return the hash of the existing vertex. + * Throws an error if any of the dependencies are not present in the hashgraph. + */ addVertex(operation: Operation, deps: Hash[], nodeId: string): Hash { const hash = computeHash(nodeId, operation, deps); if (this.vertices.has(hash)) { return hash; // Vertex already exists } - // Temporary fix: don't add the vertex if the dependencies are not present in the local HG. if ( !deps.every((dep) => this.forwardEdges.has(dep) || this.vertices.has(dep)) ) { - console.error("Invalid dependency detected."); - return ""; + throw new Error("Invalid dependency detected."); } const vertex: Vertex = { diff --git a/packages/object/src/index.ts b/packages/object/src/index.ts index 3389003a..d9d0b627 100644 --- a/packages/object/src/index.ts +++ b/packages/object/src/index.ts @@ -97,18 +97,27 @@ export class TopologyObject implements ITopologyObject { this._notify("callFn", [serializedVertex]); } - merge(vertices: Vertex[]) { + /* Merges the vertices into the hashgraph + * Returns a tuple with a boolean indicating if there were + * missing vertices and an array with the missing vertices + */ + merge(vertices: Vertex[]): [merged: boolean, missing: string[]] { + const missing = []; for (const vertex of vertices) { // Check to avoid manually crafted `undefined` operations if (!vertex.operation) { continue; } - this.hashGraph.addVertex( - vertex.operation, - vertex.dependencies, - vertex.nodeId, - ); + try { + this.hashGraph.addVertex( + vertex.operation, + vertex.dependencies, + vertex.nodeId, + ); + } catch (e) { + missing.push(vertex.hash); + } } const operations = this.hashGraph.linearizeOperations(); @@ -116,6 +125,8 @@ export class TopologyObject implements ITopologyObject { (this.cro as CRO).mergeCallback(operations); this._notify("merge", this.vertices); + + return [missing.length === 0, missing]; } subscribe(callback: TopologyObjectCallback) { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1568ae07..0257e9f2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -45,16 +45,16 @@ importers: examples/canvas: dependencies: '@topology-foundation/blueprints': - specifier: 0.3.0 + specifier: 0.3.1 version: link:../../packages/blueprints '@topology-foundation/network': - specifier: 0.3.0 + specifier: 0.3.1 version: link:../../packages/network '@topology-foundation/node': - specifier: 0.3.0 + specifier: 0.3.1 version: link:../../packages/node '@topology-foundation/object': - specifier: 0.3.0 + specifier: 0.3.1 version: link:../../packages/object crypto-browserify: specifier: ^3.12.0 @@ -91,16 +91,16 @@ importers: examples/chat: dependencies: '@topology-foundation/blueprints': - specifier: 0.3.0 + specifier: 0.3.1 version: link:../../packages/blueprints '@topology-foundation/network': - specifier: 0.3.0 + specifier: 0.3.1 version: link:../../packages/network '@topology-foundation/node': - specifier: 0.3.0 + specifier: 0.3.1 version: link:../../packages/node '@topology-foundation/object': - specifier: 0.3.0 + specifier: 0.3.1 version: link:../../packages/object assemblyscript: specifier: ^0.27.29 @@ -143,13 +143,13 @@ importers: examples/grid: dependencies: '@topology-foundation/network': - specifier: 0.3.0 + specifier: 0.3.1 version: link:../../packages/network '@topology-foundation/node': - specifier: 0.3.0 + specifier: 0.3.1 version: link:../../packages/node '@topology-foundation/object': - specifier: 0.3.0 + specifier: 0.3.1 version: link:../../packages/object assemblyscript: specifier: ^0.27.29 @@ -198,16 +198,16 @@ importers: examples/local-bootstrap: dependencies: '@topology-foundation/blueprints': - specifier: 0.3.0 + specifier: 0.3.1 version: link:../../packages/blueprints '@topology-foundation/network': - specifier: 0.3.0 + specifier: 0.3.1 version: link:../../packages/network '@topology-foundation/node': - specifier: 0.3.0 + specifier: 0.3.1 version: link:../../packages/node '@topology-foundation/object': - specifier: 0.3.0 + specifier: 0.3.1 version: link:../../packages/object assemblyscript: specifier: ^0.27.29 @@ -254,7 +254,7 @@ importers: version: 4.1.2 devDependencies: '@topology-foundation/object': - specifier: 0.3.0 + specifier: 0.3.1 version: link:../object assemblyscript: specifier: ^0.27.29 @@ -326,7 +326,7 @@ importers: specifier: ^12.3.1 version: 12.3.1 '@topology-foundation/logger': - specifier: ^0.3.0 + specifier: ^0.3.1 version: link:../logger it-length-prefixed: specifier: ^9.1.0 @@ -366,16 +366,16 @@ importers: specifier: ^2.1.3 version: 2.2.0 '@topology-foundation/blueprints': - specifier: 0.3.0 + specifier: 0.3.1 version: link:../blueprints '@topology-foundation/logger': - specifier: 0.3.0 + specifier: 0.3.1 version: link:../logger '@topology-foundation/network': - specifier: 0.3.0 + specifier: 0.3.1 version: link:../network '@topology-foundation/object': - specifier: 0.3.0 + specifier: 0.3.1 version: link:../object commander: specifier: ^12.1.0 @@ -409,7 +409,7 @@ importers: specifier: ^2.0.0 version: 2.2.1 '@topology-foundation/logger': - specifier: ^0.3.0 + specifier: ^0.3.1 version: link:../logger ts-proto: specifier: ^2.2.4