From 415bf3e98bd0b087ef20f597d38a592b587239d6 Mon Sep 17 00:00:00 2001 From: KimlikDAO-bot Date: Fri, 24 May 2024 17:12:13 -0700 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=9A=20Improve=20Mina=20Merkle=20path?= =?UTF-8?q?=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib | 2 +- mina/Makefile | 17 +++++------ mina/MinaState.js | 18 ++++++++++-- mina/mina.d.js | 12 ++------ mina/mina.js | 73 ++++++++++++++++++++++++++++++++++++----------- mina/prod.toml | 6 +--- 6 files changed, 85 insertions(+), 43 deletions(-) diff --git a/lib b/lib index 29c7b94..284422c 160000 --- a/lib +++ b/lib @@ -1 +1 @@ -Subproject commit 29c7b94173643e5758aa2e638e8b96d845d35406 +Subproject commit 284422c9d0f52b6260eda165ee3182de78a4b731 diff --git a/mina/Makefile b/mina/Makefile index 0bb01c0..f9957bc 100644 --- a/mina/Makefile +++ b/mina/Makefile @@ -1,33 +1,30 @@ include mina/test/Makefile build/mina/mina.js: mina/mina.js mina/mina.d.js \ - mina/MerkleTree.js \ + mina/MerkleTree.js mina/MinaState.js \ $(lib)/cloudflare/moduleWorker.d.js \ $(lib)/cloudflare/durableObject.d.js \ $(lib)/cloudflare/types.d.js \ $(lib)/crypto/poseidon.js \ $(lib)/crypto/modular.js \ $(lib)/mina/mina.d.js \ - $(lib)/util/hex.js + $(lib)/util/merkleTree.js $(lib)/util/hex.js mkdir -p $(dir $@) mkdir -p build/input/mina && cp -rf mina/* build/input/mina/ mkdir -p build/input/node_modules/@kimlikdao ln -sfn ../../../../$(lib) build/input/node_modules/@kimlikdao/lib sed -i.bak '/cloudflare:workers/d' build/input/mina/MerkleTree.js - echo 'globalThis["MinaWorker"] = MinaWorker;\nglobalThis["MerkleTree"] = MerkleTree;' >> build/input/mina/mina.js - cd build/input; bun google-closure-compiler $(GCC_MODULE) \ + sed -i.bak '/cloudflare:workers/d' build/input/mina/MinaState.js + echo 'globalThis["MinaWorker"] = MinaWorker;\nglobalThis["MerkleTree"] = MerkleTree;\nglobalThis["MinaState"] = MinaState;' >> build/input/mina/mina.js + cd build/input; bun google-closure-compiler $(call gccModule, $^, ../../$@) \ --jscomp_error=checkTypes \ --jscomp_error=strictCheckTypes \ - --jscomp_error=unusedLocalVariables \ - --jscomp_error=reportUnknownTypes \ - --entry_point $< \ - --js $^ \ - --js_output_file ../../$@ + --jscomp_error=unusedLocalVariables rm -rf build/input/ bun uglifyjs $@ -m -c toplevel,unsafe,drop_console -o $@ bun $(lib)/birimler/bigintCompressor.js $@ wc $@ build/mina.deployment: build/mina/mina.js mina/prod.toml - bun wrangler deploy $< --compatibility-date $(shell date -v -1d +%Y-%m-%d) \ + bun wrangler deploy --compatibility-date $(shell date -v -1d +%Y-%m-%d) \ --config mina/prod.toml diff --git a/mina/MinaState.js b/mina/MinaState.js index b356d47..45c936c 100644 --- a/mina/MinaState.js +++ b/mina/MinaState.js @@ -1,21 +1,35 @@ import { DurableObject } from "cloudflare:workers"; +/** + * @implements {cloudflare.DurableObject} + */ class MinaState extends DurableObject { + /** + * @param {!cloudflare.DurableObjectState} state + * @param {!cloudflare.Environment} env + */ constructor(state, env) { super(state, env); - /** @const {!cloudflare.DurableobjectStorage} */ + /** @const {!cloudflare.DurableObjectStorage} */ this.storage = state.storage; /** @type {number} */ this.height = 0; state.blockConcurrencyWhile(() => state.storage.get("height") - .then((/** nummber */ height) => this.height = height)); + .then((/** number */ height) => this.height = height || 0)); } + /** + * @return {number} + */ getHeight() { return this.height; } + /** + * @param {number} height + * @return {!Promise} + */ setHeight(height) { this.height = height; return this.storage.put("height", height); diff --git a/mina/mina.d.js b/mina/mina.d.js index 1cd6f71..71de362 100644 --- a/mina/mina.d.js +++ b/mina/mina.d.js @@ -1,14 +1,5 @@ /** @externs */ -/** - * @constructor - * @implements {cloudflare.DurableObject} - * - * @param {!cloudflare.DurableObjectState} state - * @param {!cloudflare.Environment} env - */ -const DurableObject = function (state, env) { } - /** * @interface * @extends {cloudflare.Environment} @@ -17,3 +8,6 @@ const MinaEnv = function () { } /** @const {!cloudflare.DurableObjectBinding} */ MinaEnv.prototype.MerkleTree; + +/** @const {!cloudflare.DurableObjectBinding} */ +MinaEnv.prototype.MinaState; diff --git a/mina/mina.js b/mina/mina.js index 12a2277..5b9d152 100644 --- a/mina/mina.js +++ b/mina/mina.js @@ -1,4 +1,3 @@ -import hex from "@kimlikdao/lib/util/hex"; import { MerkleTree } from "./MerkleTree"; import { MinaState } from "./MinaState"; @@ -47,17 +46,19 @@ const MinaWorker = { const merkleTree = /** @type {!MerkleTree} */ ( env.MerkleTree.get(env.MerkleTree.idFromName(address))); - return merkleTree.getWitness(index).then((witness) => { - console.log(witness); - witness.forEach((w) => w.sibling = w.sibling.toString(16)); - return new Response(JSON.stringify(witness), { + return merkleTree.getWitness(index).then((witness) => + new Response(JSON.stringify(witness.map((w) => /** @type {mina.Witness} */({ + sibling: w.sibling.toString(16), + isLeft: w.isLeft + }))), { headers: { 'content-type': 'application/json', 'access-control-allow-origin': '*' } }) - }); + ); } + return Promise.reject(); }, /** @@ -65,25 +66,59 @@ const MinaWorker = { * * A very simple and error prone Mina sychronization method. * Will not survive forks. + * + * @param {!MinaEnv} env */ async scheduled(event, env) { /** @const {!MerkleTree} */ - const merkleTree = env.MerkleTree.get(env.MerkleTree.idFromName(LEARN2EARN)); + const merkleTree = /** @type {!MerkleTree} */(env.MerkleTree.get(env.MerkleTree.idFromName(LEARN2EARN))); /** @const {!MinaState} */ - const minaState = env.MinaState.get(env.MinaState.idFromName("")); - /** @const */ - const lastHeight = minaState.getHeight(); + const minaState = /** @type {!MinaState} */(env.MinaState.get(env.MinaState.idFromName(""))); + /** @const {number} */ + const lastHeight = await minaState.getHeight(); + console.log("Last height", lastHeight); + + /** + * @typedef {{ + * height: number + * }} + */ + const BlockInfo = {}; + + /** + * @typedef {{ + * status: string + * }} + */ + const TransactionInfo = {}; - let events = await fetch(MINA_NODE_URL, { + /** + * @typedef {{ + * transactionInfo: TransactionInfo, + * data: !Array + * }} + */ + const EventData = {}; + + /** + * @typedef {{ + * blockInfo: BlockInfo, + * eventData: !Array + * }} + */ + const EventInfo = {}; + + /** @type {!Array} */ + let events = /** @type {!Array} */(await fetch(MINA_NODE_URL, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ query: EventsQuery }), }) .then((res) => res.json()) - .then((data) => data["data"]["events"].filter((e) => + .then((data) => /** !Array */(data["data"]["events"]).filter((/** EventInfo */ e) => e.eventData[0].transactionInfo.status == "applied" && e.blockInfo.height > lastHeight - )); + ))); events.sort((x, y) => x.blockInfo.height - y.blockInfo.height); for (const e of events) { @@ -91,14 +126,20 @@ const MinaWorker = { switch (type) { case "1": await merkleTree.setHeight(+val); + console.log(`height set ${+val}`); break; - case "0": await merkleTree.setLeaf( - BigInt(val).toString(16) & 0xffffffffn); + case "0": + await merkleTree.setLeaf(BigInt(val).toString(16), 1n); + console.log(`leaf set ${val}`); break; } } - return minaState.setHeight(events[events.length - 1].blockInfo.height); + if (events.length) { + const height = +(events.pop().blockInfo.height); + console.log(`mina state height set ${height}`); + await minaState.setHeight(height); + } }, }; diff --git a/mina/prod.toml b/mina/prod.toml index 6f4d944..5240a11 100644 --- a/mina/prod.toml +++ b/mina/prod.toml @@ -23,11 +23,7 @@ class_name = "MinaState" [[migrations]] tag = "v1" -new_classes = ["MerkleTree"] - -[[migrations]] -tag = "v2" -new_classes = ["MinaState"] +new_classes = ["MerkleTree", "MinaState"] [triggers] crons = ["* * * * *"]