@gas-killer/analyzer-wasm 0.3.1 → 0.4.0

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.
package/README.md CHANGED
@@ -11,7 +11,7 @@ npm install @gas-killer/analyzer-wasm
11
11
  The package is built for the web target. Initialize it once before calling anything:
12
12
 
13
13
  ```js
14
- import init, { analyze_trace, analyze_prestate } from "@gas-killer/analyzer-wasm"
14
+ import init, { analyze_trace_bytes, analyze_prestate } from "@gas-killer/analyzer-wasm"
15
15
 
16
16
  await init() // in Node: initSync({ module: fs.readFileSync(".../gas_killer_wasm_bg.wasm") })
17
17
  ```
@@ -30,6 +30,23 @@ const result = analyze_trace(JSON.stringify(trace), estimator, receipt.from, Big
30
30
  // { gas_estimate, is_heuristic, encoded_updates, state_update_count, skipped_opcodes, reentered }
31
31
  ```
32
32
 
33
+ ### `analyze_trace_bytes(response, estimator, caller, block?, origin?)`
34
+
35
+ Takes the same arguments as `analyze_trace`, except that it accepts the whole JSON-RPC response body as a `Uint8Array`. Use it for large traces:
36
+
37
+ - The trace is never decoded into a JavaScript string, so it isn't held twice and isn't subject to the string length limit.
38
+ - Memory snapshots are skipped for steps that don't need them, so the analysis uses about 1.4× the response's size in wasm memory.
39
+
40
+ ```js
41
+ const response = new Uint8Array(await (await fetch(rpcUrl, { method: "POST", body })).arrayBuffer())
42
+ try {
43
+ const result = analyze_trace_bytes(response, estimator, receipt.from, BigInt(receipt.blockNumber), receipt.to)
44
+ } catch (e) {
45
+ // e.name is "RpcError" when the node returned an error, or "TraceTooLargeError" when the error
46
+ // was the provider's response size limit
47
+ }
48
+ ```
49
+
33
50
  ### `analyze_prestate(diff, callFrame, consumer, estimator, caller, block?)`
34
51
 
35
52
  Analyzes the same transaction from two much smaller traces:
@@ -68,6 +68,16 @@ export function analyze_prestate(diff_json: string, call_frame_json: string, con
68
68
  */
69
69
  export function analyze_trace(trace_json: string, estimator_address: string, caller_address: string, estimate_state_changes_block_number?: bigint | null, origin_address?: string | null): any;
70
70
 
71
+ /**
72
+ * [`analyze_trace`] on the raw bytes of a whole `debug_traceTransaction` JSON-RPC response, so a
73
+ * large trace never has to be decoded into a JS string or unwrapped from its envelope in JS.
74
+ *
75
+ * When the node answered with an error, throws an `Error` named `RpcError` with the node's
76
+ * message, or `TraceTooLargeError` when the message is the provider's response size limit.
77
+ * Other failures throw a plain `Error`, as [`analyze_trace`] does.
78
+ */
79
+ export function analyze_trace_bytes(response: Uint8Array, estimator_address: string, caller_address: string, estimate_state_changes_block_number?: bigint | null, origin_address?: string | null): any;
80
+
71
81
  /**
72
82
  * Encode state updates only (no gas estimation).
73
83
  */
@@ -91,6 +101,7 @@ export interface InitOutput {
91
101
  readonly memory: WebAssembly.Memory;
92
102
  readonly analyze_prestate: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: bigint) => [number, number, number];
93
103
  readonly analyze_trace: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: bigint, i: number, j: number) => [number, number, number];
104
+ readonly analyze_trace_bytes: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: bigint, i: number, j: number) => [number, number, number];
94
105
  readonly encode_trace: (a: number, b: number) => [number, number, number];
95
106
  readonly estimate_gas_heuristic: (a: number, b: number, c: number, d: number) => [number, number, number];
96
107
  readonly init: () => void;
@@ -25,6 +25,13 @@ function isLikeNone(x) {
25
25
  return x === undefined || x === null;
26
26
  }
27
27
 
28
+ function passArray8ToWasm0(arg, malloc) {
29
+ const ptr = malloc(arg.length * 1, 1) >>> 0;
30
+ getUint8ArrayMemory0().set(arg, ptr / 1);
31
+ WASM_VECTOR_LEN = arg.length;
32
+ return ptr;
33
+ }
34
+
28
35
  function passStringToWasm0(arg, malloc, realloc) {
29
36
  if (realloc === undefined) {
30
37
  const buf = cachedTextEncoder.encode(arg);
@@ -176,6 +183,36 @@ export function analyze_trace(trace_json, estimator_address, caller_address, est
176
183
  return takeFromExternrefTable0(ret[0]);
177
184
  }
178
185
 
186
+ /**
187
+ * [`analyze_trace`] on the raw bytes of a whole `debug_traceTransaction` JSON-RPC response, so a
188
+ * large trace never has to be decoded into a JS string or unwrapped from its envelope in JS.
189
+ *
190
+ * When the node answered with an error, throws an `Error` named `RpcError` with the node's
191
+ * message, or `TraceTooLargeError` when the message is the provider's response size limit.
192
+ * Other failures throw a plain `Error`, as [`analyze_trace`] does.
193
+ * @param {Uint8Array} response
194
+ * @param {string} estimator_address
195
+ * @param {string} caller_address
196
+ * @param {bigint | null} [estimate_state_changes_block_number]
197
+ * @param {string | null} [origin_address]
198
+ * @returns {any}
199
+ */
200
+ export function analyze_trace_bytes(response, estimator_address, caller_address, estimate_state_changes_block_number, origin_address) {
201
+ const ptr0 = passArray8ToWasm0(response, wasm.__wbindgen_malloc);
202
+ const len0 = WASM_VECTOR_LEN;
203
+ const ptr1 = passStringToWasm0(estimator_address, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
204
+ const len1 = WASM_VECTOR_LEN;
205
+ const ptr2 = passStringToWasm0(caller_address, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
206
+ const len2 = WASM_VECTOR_LEN;
207
+ var ptr3 = isLikeNone(origin_address) ? 0 : passStringToWasm0(origin_address, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
208
+ var len3 = WASM_VECTOR_LEN;
209
+ const ret = wasm.analyze_trace_bytes(ptr0, len0, ptr1, len1, ptr2, len2, !isLikeNone(estimate_state_changes_block_number), isLikeNone(estimate_state_changes_block_number) ? BigInt(0) : estimate_state_changes_block_number, ptr3, len3);
210
+ if (ret[2]) {
211
+ throw takeFromExternrefTable0(ret[1]);
212
+ }
213
+ return takeFromExternrefTable0(ret[0]);
214
+ }
215
+
179
216
  /**
180
217
  * Encode state updates only (no gas estimation).
181
218
  * @param {string} trace_json
@@ -290,12 +327,19 @@ function __wbg_get_imports() {
290
327
  const ret = new Error();
291
328
  return ret;
292
329
  };
330
+ imports.wbg.__wbg_new_df1173567d5ff028 = function(arg0, arg1) {
331
+ const ret = new Error(getStringFromWasm0(arg0, arg1));
332
+ return ret;
333
+ };
293
334
  imports.wbg.__wbg_set_3f1d0b984ed272ed = function(arg0, arg1, arg2) {
294
335
  arg0[arg1] = arg2;
295
336
  };
296
337
  imports.wbg.__wbg_set_7df433eea03a5c14 = function(arg0, arg1, arg2) {
297
338
  arg0[arg1 >>> 0] = arg2;
298
339
  };
340
+ imports.wbg.__wbg_set_name_df69b75cb0b4de8a = function(arg0, arg1, arg2) {
341
+ arg0.name = getStringFromWasm0(arg1, arg2);
342
+ };
299
343
  imports.wbg.__wbg_stack_0ed75d68575b0f3c = function(arg0, arg1) {
300
344
  const ret = arg1.stack;
301
345
  const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
Binary file
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@gas-killer/analyzer-wasm",
3
3
  "type": "module",
4
4
  "description": "Gas Killer's WebAssembly gas analyzer: estimates a transaction's gas savings from its Geth trace in the browser",
5
- "version": "0.3.1",
5
+ "version": "0.4.0",
6
6
  "license": "SEE LICENSE IN LICENSE",
7
7
  "files": [
8
8
  "gas_killer_wasm_bg.wasm",