@hazae41/bobine 0.0.10 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,6 +6,8 @@ export declare class Pack {
6
6
  writeOrThrow(cursor: Cursor): void;
7
7
  }
8
8
  export declare namespace Pack {
9
- type Value = null | Pack | number | Uint8Array | string | bigint;
10
- function readOrThrow(cursor: Cursor): Pack;
9
+ type Value = null | number | Uint8Array | string | bigint | Array<Value>;
10
+ function readOrThrow(cursor: Cursor): Array<Value>;
11
+ function sizeOrThrow(values: Array<Value>): number;
12
+ function writeOrThrow(values: Array<Value>, cursor: Cursor): void;
11
13
  }
@@ -5,14 +5,64 @@ export class Pack {
5
5
  this.values = values;
6
6
  }
7
7
  sizeOrThrow() {
8
+ return Pack.sizeOrThrow(this.values);
9
+ }
10
+ writeOrThrow(cursor) {
11
+ Pack.writeOrThrow(this.values, cursor);
12
+ }
13
+ }
14
+ (function (Pack) {
15
+ function readOrThrow(cursor) {
16
+ const values = [];
17
+ while (true) {
18
+ const type = cursor.readUint8OrThrow();
19
+ if (type === 0)
20
+ break;
21
+ if (type === 1) {
22
+ values.push(null);
23
+ continue;
24
+ }
25
+ if (type === 2) {
26
+ values.push(Pack.readOrThrow(cursor));
27
+ continue;
28
+ }
29
+ if (type === 3) {
30
+ values.push(cursor.readFloat64OrThrow(true));
31
+ continue;
32
+ }
33
+ if (type === 4) {
34
+ const size = cursor.readUint32OrThrow(true);
35
+ values.push(cursor.readOrThrow(size));
36
+ continue;
37
+ }
38
+ if (type === 5) {
39
+ const size = cursor.readUint32OrThrow(true);
40
+ const data = cursor.readOrThrow(size);
41
+ values.push(new TextDecoder().decode(data));
42
+ continue;
43
+ }
44
+ if (type === 6) {
45
+ const negative = cursor.readUint8OrThrow();
46
+ const size = cursor.readUint32OrThrow(true);
47
+ const data = cursor.readOrThrow(size);
48
+ const absolute = BigInt("0x" + data.toHex());
49
+ values.push(negative ? -absolute : absolute);
50
+ continue;
51
+ }
52
+ throw new Error("Unknown pack type");
53
+ }
54
+ return values;
55
+ }
56
+ Pack.readOrThrow = readOrThrow;
57
+ function sizeOrThrow(values) {
8
58
  let size = 0;
9
- for (const value of this.values) {
59
+ for (const value of values) {
10
60
  if (value == null) {
11
61
  size += 1;
12
62
  continue;
13
63
  }
14
- if (value instanceof Pack) {
15
- size += 1 + value.sizeOrThrow();
64
+ if (Array.isArray(value)) {
65
+ size += 1 + sizeOrThrow(value);
16
66
  continue;
17
67
  }
18
68
  if (typeof value === "number") {
@@ -29,9 +79,10 @@ export class Pack {
29
79
  continue;
30
80
  }
31
81
  if (typeof value === "bigint") {
32
- const text = value.toString(16);
82
+ const absolute = value < 0n ? -value : value;
83
+ const text = absolute.toString(16);
33
84
  const data = Uint8Array.fromHex(text.length % 2 === 1 ? "0" + text : text);
34
- size += 1 + 4 + data.length;
85
+ size += 1 + 1 + 4 + data.length;
35
86
  continue;
36
87
  }
37
88
  throw new Error("Unknown pack value");
@@ -39,15 +90,16 @@ export class Pack {
39
90
  size += 1;
40
91
  return size;
41
92
  }
42
- writeOrThrow(cursor) {
43
- for (const value of this.values) {
93
+ Pack.sizeOrThrow = sizeOrThrow;
94
+ function writeOrThrow(values, cursor) {
95
+ for (const value of values) {
44
96
  if (value == null) {
45
97
  cursor.writeUint8OrThrow(1);
46
98
  continue;
47
99
  }
48
- if (value instanceof Pack) {
100
+ if (Array.isArray(value)) {
49
101
  cursor.writeUint8OrThrow(2);
50
- value.writeOrThrow(cursor);
102
+ writeOrThrow(value, cursor);
51
103
  continue;
52
104
  }
53
105
  if (typeof value === "number") {
@@ -70,8 +122,10 @@ export class Pack {
70
122
  }
71
123
  if (typeof value === "bigint") {
72
124
  cursor.writeUint8OrThrow(6);
73
- const text = value.toString(16);
125
+ const [negative, absolute] = value < 0n ? [1, -value] : [0, value];
126
+ const text = absolute.toString(16);
74
127
  const data = Uint8Array.fromHex(text.length % 2 === 1 ? "0" + text : text);
128
+ cursor.writeUint8OrThrow(negative);
75
129
  cursor.writeUint32OrThrow(data.length, true);
76
130
  cursor.writeOrThrow(data);
77
131
  continue;
@@ -81,46 +135,5 @@ export class Pack {
81
135
  cursor.writeUint8OrThrow(0);
82
136
  return;
83
137
  }
84
- }
85
- (function (Pack) {
86
- function readOrThrow(cursor) {
87
- const values = [];
88
- while (true) {
89
- const type = cursor.readUint8OrThrow();
90
- if (type === 0)
91
- break;
92
- if (type === 1) {
93
- values.push(null);
94
- continue;
95
- }
96
- if (type === 2) {
97
- values.push(Pack.readOrThrow(cursor));
98
- continue;
99
- }
100
- if (type === 3) {
101
- values.push(cursor.readFloat64OrThrow(true));
102
- continue;
103
- }
104
- if (type === 4) {
105
- const size = cursor.readUint32OrThrow(true);
106
- values.push(cursor.readOrThrow(size));
107
- continue;
108
- }
109
- if (type === 5) {
110
- const size = cursor.readUint32OrThrow(true);
111
- const data = cursor.readOrThrow(size);
112
- values.push(new TextDecoder().decode(data));
113
- continue;
114
- }
115
- if (type === 6) {
116
- const size = cursor.readUint32OrThrow(true);
117
- const data = cursor.readOrThrow(size);
118
- values.push(BigInt("0x" + data.toHex()));
119
- continue;
120
- }
121
- throw new Error("Unknown pack type");
122
- }
123
- return new Pack(values);
124
- }
125
- Pack.readOrThrow = readOrThrow;
138
+ Pack.writeOrThrow = writeOrThrow;
126
139
  })(Pack || (Pack = {}));
@@ -4,7 +4,6 @@ import { RpcErr, RpcError, RpcMethodNotFoundError, RpcOk } from "@hazae41/jsonrp
4
4
  import * as Wasm from "@hazae41/wasm";
5
5
  import { Buffer } from "node:buffer";
6
6
  import { existsSync, readFileSync, symlinkSync, writeFileSync } from "node:fs";
7
- import { log } from "../../libs/debug/mod.js";
8
7
  import { meter } from "../../libs/metering/mod.js";
9
8
  import { Pack } from "../../libs/packs/mod.js";
10
9
  const config = await fetch(self.name).then(res => res.json());
@@ -13,9 +12,11 @@ function run(module, method, params, mode, maxsparks) {
13
12
  let sparks = 0n;
14
13
  const exports = {};
15
14
  const caches = new Map();
15
+ const logs = new Array();
16
+ const reads = new Array();
16
17
  const writes = new Array();
17
18
  const pack_encode = (pack) => {
18
- return Writable.writeToBytesOrThrow(pack);
19
+ return Writable.writeToBytesOrThrow(new Pack(pack));
19
20
  };
20
21
  const pack_decode = (bytes) => {
21
22
  return Readable.readFromBytesOrThrow(Pack, bytes);
@@ -48,7 +49,7 @@ function run(module, method, params, mode, maxsparks) {
48
49
  };
49
50
  const ed25519_sign = (subpayload) => {
50
51
  sparks_consume(BigInt(subpayload.length) * 256n);
51
- const payload = pack_encode(new Pack([Uint8Array.fromHex(module), subpayload]));
52
+ const payload = pack_encode([Uint8Array.fromHex(module), subpayload]);
52
53
  const result = new Int32Array(new SharedArrayBuffer(4 + 64));
53
54
  helper.postMessage({ method: "ed25519_sign", params: [payload], result });
54
55
  if (Atomics.wait(result, 0, 0) !== "ok")
@@ -79,8 +80,8 @@ function run(module, method, params, mode, maxsparks) {
79
80
  }
80
81
  };
81
82
  imports["console"] = {
82
- log: (blob) => {
83
- log?.(new TextDecoder().decode(blob));
83
+ log: (text) => {
84
+ logs.push(text);
84
85
  }
85
86
  };
86
87
  imports["blobs"] = {
@@ -159,16 +160,16 @@ function run(module, method, params, mode, maxsparks) {
159
160
  };
160
161
  imports["packs"] = {
161
162
  create: (...values) => {
162
- return new Pack(values);
163
+ return values;
163
164
  },
164
165
  concat: (left, right) => {
165
- return new Pack([...left.values, ...right.values]);
166
+ return [...left, ...right];
166
167
  },
167
168
  length: (pack) => {
168
- return pack.values.length;
169
+ return pack.length;
169
170
  },
170
171
  get(pack, index) {
171
- const value = pack.values[index >>> 0];
172
+ const value = pack[index >>> 0];
172
173
  if (value === undefined)
173
174
  throw new Error("Not found");
174
175
  return value;
@@ -181,6 +182,9 @@ function run(module, method, params, mode, maxsparks) {
181
182
  }
182
183
  };
183
184
  imports["bigints"] = {
185
+ identity: (value) => {
186
+ return value;
187
+ },
184
188
  zero: () => {
185
189
  return 0n;
186
190
  },
@@ -244,21 +248,21 @@ function run(module, method, params, mode, maxsparks) {
244
248
  return BigInt("0x" + bytes.toHex());
245
249
  },
246
250
  from_base16: (text) => {
247
- return BigInt("0x" + new TextDecoder().decode(text));
251
+ return BigInt("0x" + text);
248
252
  },
249
253
  to_base16: (bigint) => {
250
- return new TextEncoder().encode(bigint.toString(16));
254
+ return bigint.toString(16);
251
255
  },
252
256
  from_base10: (text) => {
253
- return BigInt(new TextDecoder().decode(text));
257
+ return BigInt(text);
254
258
  },
255
259
  to_base10: (bigint) => {
256
- return new TextEncoder().encode(bigint.toString());
260
+ return bigint.toString();
257
261
  }
258
262
  };
259
263
  imports["modules"] = {
260
264
  create: (wasmAsBytes, saltAsBytes) => {
261
- const packAsBytes = pack_encode(new Pack([wasmAsBytes, saltAsBytes]));
265
+ const packAsBytes = pack_encode([wasmAsBytes, saltAsBytes]);
262
266
  const digestOfWasmAsBytes = sha256_digest(wasmAsBytes);
263
267
  const digestOfPackAsBytes = sha256_digest(packAsBytes);
264
268
  const digestOfWasmAsHex = digestOfWasmAsBytes.toHex();
@@ -307,6 +311,7 @@ function run(module, method, params, mode, maxsparks) {
307
311
  return null;
308
312
  const fresh = new Uint8Array(result.buffer, 4 + 4 + 4, result[2]).slice();
309
313
  cache.set(key, fresh);
314
+ reads.push([module, key, fresh]);
310
315
  return fresh;
311
316
  }
312
317
  };
@@ -380,37 +385,33 @@ function run(module, method, params, mode, maxsparks) {
380
385
  const { instance } = load(module);
381
386
  if (typeof instance.exports[method] !== "function")
382
387
  throw new Error("Not found");
383
- const result = pack_encode(new Pack([instance.exports[method](...pack_decode(params).values)]));
384
- return { result, writes, sparks };
388
+ const returned = [instance.exports[method](...pack_decode(params))];
389
+ if (mode !== 2)
390
+ return pack_encode([logs, reads, writes, returned, sparks]);
391
+ if (writes.length) {
392
+ const result = new Int32Array(new SharedArrayBuffer(4 + 4));
393
+ helper.postMessage({ method: "storage_set", params: [module, method, params, writes], result });
394
+ if (Atomics.wait(result, 0, 0) !== "ok")
395
+ throw new Error("Failed to wait");
396
+ if (result[0] === 2)
397
+ throw new Error("Internal error");
398
+ // NOOP
399
+ }
400
+ return pack_encode([logs, reads, writes, returned, sparks]);
385
401
  }
386
402
  self.addEventListener("message", (event) => {
387
403
  try {
388
404
  const request = event.data;
389
405
  if (request.method === "execute") {
390
406
  const [module, method, params, maxsparks] = request.params;
391
- const start = performance.now();
392
- const { result, writes, sparks } = run(module, method, params, 1, maxsparks);
393
- const until = performance.now();
394
- log?.(`Evaluated ${(until - start).toFixed(2)}ms with ${sparks} sparks`);
395
- if (writes.length) {
396
- const result = new Int32Array(new SharedArrayBuffer(4 + 4));
397
- helper.postMessage({ method: "storage_set", params: [module, method, params, writes], result });
398
- if (Atomics.wait(result, 0, 0) !== "ok")
399
- throw new Error("Failed to wait");
400
- if (result[0] === 2)
401
- throw new Error("Internal error");
402
- log?.(`Wrote ${writes.length} events to storage`);
403
- }
404
- self.postMessage(new RpcOk(request.id, result));
407
+ const proof = run(module, method, params, 1, maxsparks);
408
+ self.postMessage(new RpcOk(request.id, proof));
405
409
  return;
406
410
  }
407
411
  if (request.method === "simulate") {
408
412
  const [module, method, params, maxsparks] = request.params;
409
- const start = performance.now();
410
- const { result, sparks } = run(module, method, params, 2, maxsparks);
411
- const until = performance.now();
412
- log?.(`Evaluated ${(until - start).toFixed(2)}ms with ${sparks} sparks`);
413
- self.postMessage(new RpcOk(request.id, result));
413
+ const proof = run(module, method, params, 2, maxsparks);
414
+ self.postMessage(new RpcOk(request.id, proof));
414
415
  return;
415
416
  }
416
417
  if (request.method === "verify") {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@hazae41/bobine",
4
- "version": "0.0.10",
4
+ "version": "0.0.11",
5
5
  "description": "A blockchain in your garage",
6
6
  "repository": "github:hazae41/bobine",
7
7
  "author": "hazae41",
@@ -1 +0,0 @@
1
- export declare const log: (message: string) => void;
@@ -1,4 +0,0 @@
1
- import process from "node:process";
2
- export const log = process.env.NODE_ENV === "development"
3
- ? (message) => console.debug(message)
4
- : null;