@fluffylabs/anan-as 1.2.0-9723cd9 → 1.2.0-9f08a39

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.
Binary file
@@ -0,0 +1,166 @@
1
+ #!/usr/bin/env node
2
+ import * as assert from "node:assert";
3
+ import { parseTrace } from "../bin/src/trace-parse.js";
4
+ // Test: round-trip parse of a spec-compliant trace
5
+ {
6
+ const input = [
7
+ "program 0x0102aabbccddeeff",
8
+ "memwrite 0x00001000 len=8 <- 0x0000000000000001",
9
+ "start pc=0 gas=10000 r07=0x10 r09=0x10000",
10
+ "",
11
+ "ecalli=10 pc=42 gas=9980 r01=0x1 r03=0x1000",
12
+ "memread 0x00001000 len=4 -> 0x01020304",
13
+ "memread 0x00001020 len=8 -> 0x0000000000000040",
14
+ "memwrite 0x00002000 len=2 <- 0xffee",
15
+ "setreg r00 <- 0x100",
16
+ "setreg r02 <- 0x4",
17
+ "setgas <- 9950",
18
+ "",
19
+ "HALT pc=42 gas=9920 r00=0x100 r02=0x4",
20
+ ].join("\n");
21
+ const trace = parseTrace(input);
22
+ // Program
23
+ assert.deepStrictEqual(Array.from(trace.program), [0x01, 0x02, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff], "program bytes");
24
+ // Initial memwrite
25
+ assert.strictEqual(trace.initialMemWrites.length, 1, "one initial memwrite");
26
+ assert.strictEqual(trace.initialMemWrites[0].address, 0x00001000, "memwrite address");
27
+ assert.strictEqual(trace.initialMemWrites[0].data.length, 8, "memwrite data length");
28
+ // Start
29
+ assert.strictEqual(trace.start.pc, 0, "start pc");
30
+ assert.strictEqual(trace.start.gas, 10000n, "start gas");
31
+ assert.strictEqual(trace.start.registers.get(7), 0x10n, "start r07");
32
+ assert.strictEqual(trace.start.registers.get(9), 0x10000n, "start r09");
33
+ assert.strictEqual(trace.start.registers.has(0), false, "start r00 omitted (zero)");
34
+ // Ecalli
35
+ assert.strictEqual(trace.ecalliEntries.length, 1, "one ecalli");
36
+ const ecalli = trace.ecalliEntries[0];
37
+ assert.strictEqual(ecalli.index, 10, "ecalli index");
38
+ assert.strictEqual(ecalli.pc, 42, "ecalli pc");
39
+ assert.strictEqual(ecalli.gas, 9980n, "ecalli gas");
40
+ assert.strictEqual(ecalli.registers.get(1), 0x1n, "ecalli r01");
41
+ assert.strictEqual(ecalli.registers.get(3), 0x1000n, "ecalli r03");
42
+ // Memreads
43
+ assert.strictEqual(ecalli.memReads.length, 2, "two memreads");
44
+ assert.strictEqual(ecalli.memReads[0].address, 0x00001000, "memread 0 address");
45
+ assert.strictEqual(ecalli.memReads[0].data.length, 4, "memread 0 length");
46
+ assert.strictEqual(ecalli.memReads[1].address, 0x00001020, "memread 1 address");
47
+ // Memwrites
48
+ assert.strictEqual(ecalli.memWrites.length, 1, "one ecalli memwrite");
49
+ assert.strictEqual(ecalli.memWrites[0].address, 0x00002000, "ecalli memwrite address");
50
+ // Setregs
51
+ assert.strictEqual(ecalli.setRegs.length, 2, "two setregs");
52
+ assert.strictEqual(ecalli.setRegs[0].index, 0, "setreg 0 index");
53
+ assert.strictEqual(ecalli.setRegs[0].value, 0x100n, "setreg 0 value");
54
+ assert.strictEqual(ecalli.setRegs[1].index, 2, "setreg 1 index");
55
+ assert.strictEqual(ecalli.setRegs[1].value, 0x4n, "setreg 1 value");
56
+ // Setgas
57
+ assert.strictEqual(ecalli.setGas, 9950n, "setgas");
58
+ // Termination
59
+ assert.strictEqual(trace.termination.type, "HALT", "termination type");
60
+ assert.strictEqual(trace.termination.pc, 42, "termination pc");
61
+ assert.strictEqual(trace.termination.gas, 9920n, "termination gas");
62
+ assert.strictEqual(trace.termination.registers.get(0), 0x100n, "termination r00");
63
+ assert.strictEqual(trace.termination.registers.get(2), 0x4n, "termination r02");
64
+ console.log("PASS: spec example round-trip");
65
+ }
66
+ // Test: PANIC=0 (argument must always be present)
67
+ {
68
+ const input = ["program 0x00", "start pc=0 gas=100", "PANIC=0 pc=5 gas=50 r00=0x1"].join("\n");
69
+ const trace = parseTrace(input);
70
+ assert.strictEqual(trace.termination.type, "PANIC", "panic type");
71
+ assert.strictEqual(trace.termination.panicArg, 0, "panic arg is 0");
72
+ assert.strictEqual(trace.termination.pc, 5, "panic pc");
73
+ assert.strictEqual(trace.termination.gas, 50n, "panic gas");
74
+ console.log("PASS: PANIC=0");
75
+ }
76
+ // Test: PANIC with non-zero argument
77
+ {
78
+ const input = ["program 0x00", "start pc=0 gas=100", "PANIC=42 pc=10 gas=0"].join("\n");
79
+ const trace = parseTrace(input);
80
+ assert.strictEqual(trace.termination.panicArg, 42, "panic arg 42");
81
+ assert.strictEqual(trace.termination.registers.size, 0, "no registers");
82
+ console.log("PASS: PANIC=42");
83
+ }
84
+ // Test: OOG termination
85
+ {
86
+ const input = ["program 0x00", "start pc=0 gas=100", "OOG pc=99 gas=0"].join("\n");
87
+ const trace = parseTrace(input);
88
+ assert.strictEqual(trace.termination.type, "OOG", "OOG type");
89
+ assert.strictEqual(trace.termination.gas, 0n, "OOG gas is 0");
90
+ console.log("PASS: OOG");
91
+ }
92
+ // Test: lines with log prefixes are handled (extractPayload)
93
+ {
94
+ const input = [
95
+ "TRACE [ecalli] program 0xaa",
96
+ "TRACE [ecalli] start pc=0 gas=500 r00=0x1",
97
+ "TRACE [ecalli] HALT pc=10 gas=400",
98
+ ].join("\n");
99
+ const trace = parseTrace(input);
100
+ assert.deepStrictEqual(Array.from(trace.program), [0xaa], "prefixed program");
101
+ assert.strictEqual(trace.start.registers.get(0), 0x1n, "prefixed start r00");
102
+ assert.strictEqual(trace.termination.type, "HALT", "prefixed halt");
103
+ console.log("PASS: log-prefixed lines");
104
+ }
105
+ // Test: comment lines are ignored
106
+ {
107
+ const input = [
108
+ "comment implementation typeberry 0.8.3",
109
+ "comment chain-id fluffy-testnet",
110
+ "program 0xbb",
111
+ "comment accumulate",
112
+ "start pc=0 gas=100",
113
+ "HALT pc=5 gas=90",
114
+ ].join("\n");
115
+ const trace = parseTrace(input);
116
+ assert.deepStrictEqual(Array.from(trace.program), [0xbb], "comment lines ignored");
117
+ console.log("PASS: comment lines ignored");
118
+ }
119
+ // Test: zero-padded register indices in register dump
120
+ {
121
+ const input = ["program 0x00", "start pc=0 gas=100 r00=0xff r12=0x1", "HALT pc=5 gas=90 r00=0xff r12=0x1"].join("\n");
122
+ const trace = parseTrace(input);
123
+ assert.strictEqual(trace.start.registers.get(0), 0xffn, "r00 parsed");
124
+ assert.strictEqual(trace.start.registers.get(12), 0x1n, "r12 parsed");
125
+ console.log("PASS: zero-padded register indices");
126
+ }
127
+ // Test: empty register dump (all zeros)
128
+ {
129
+ const input = ["program 0x00", "start pc=0 gas=100", "HALT pc=5 gas=90"].join("\n");
130
+ const trace = parseTrace(input);
131
+ assert.strictEqual(trace.start.registers.size, 0, "empty register dump");
132
+ assert.strictEqual(trace.termination.registers.size, 0, "empty termination registers");
133
+ console.log("PASS: empty register dump");
134
+ }
135
+ // Test: multiple ecalli entries
136
+ {
137
+ const input = [
138
+ "program 0x00",
139
+ "start pc=0 gas=10000",
140
+ "ecalli=1 pc=10 gas=9000 r00=0x1",
141
+ "setreg r00 <- 0x2",
142
+ "ecalli=2 pc=20 gas=8000 r00=0x2",
143
+ "memwrite 0x00001000 len=1 <- 0xff",
144
+ "setgas <- 7900",
145
+ "HALT pc=30 gas=7800",
146
+ ].join("\n");
147
+ const trace = parseTrace(input);
148
+ assert.strictEqual(trace.ecalliEntries.length, 2, "two ecalli entries");
149
+ assert.strictEqual(trace.ecalliEntries[0].index, 1, "first ecalli index");
150
+ assert.strictEqual(trace.ecalliEntries[0].setRegs.length, 1, "first ecalli setregs");
151
+ assert.strictEqual(trace.ecalliEntries[0].setGas, undefined, "first ecalli no setgas");
152
+ assert.strictEqual(trace.ecalliEntries[1].index, 2, "second ecalli index");
153
+ assert.strictEqual(trace.ecalliEntries[1].memWrites.length, 1, "second ecalli memwrites");
154
+ assert.strictEqual(trace.ecalliEntries[1].setGas, 7900n, "second ecalli setgas");
155
+ console.log("PASS: multiple ecalli entries");
156
+ }
157
+ // Test: missing program throws
158
+ assert.throws(() => parseTrace("start pc=0 gas=100\nHALT pc=5 gas=90"), /Missing program/, "missing program");
159
+ console.log("PASS: missing program throws");
160
+ // Test: missing start throws
161
+ assert.throws(() => parseTrace("program 0x00\nHALT pc=5 gas=90"), /Missing start/, "missing start");
162
+ console.log("PASS: missing start throws");
163
+ // Test: missing termination throws
164
+ assert.throws(() => parseTrace("program 0x00\nstart pc=0 gas=100"), /Missing termination/, "missing termination");
165
+ console.log("PASS: missing termination throws");
166
+ console.log("\nAll trace format tests passed.");
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fluffylabs/anan-as",
3
3
  "description": "AssemblyScript PVM interpreter.",
4
- "version": "1.2.0-9723cd9",
4
+ "version": "1.2.0-9f08a39",
5
5
  "main": "./dist/bin/index.js",
6
6
  "bin": {
7
7
  "anan-as": "./dist/bin/index.js"
@@ -32,7 +32,7 @@
32
32
  "qa": "biome ci",
33
33
  "qa-fix": "npm run format; npm run lint",
34
34
  "start": "tsx ./bin/index.ts",
35
- "test": "npm run asbuild:test && tsx ./test/test-as.ts && tsx ./test/test-trace-replay.ts",
35
+ "test": "npm run asbuild:test && tsx ./test/test-as.ts && tsx ./test/test-trace-format.ts && tsx ./test/test-trace-replay.ts",
36
36
  "tsbuild": "tsc && npm run tsbuild:portable",
37
37
  "tsbuild:portable": "tsc --project portable/tsconfig.json && esbuild dist/build/js/portable/index.js --bundle --format=esm --platform=node --outfile=dist/build/js/portable-bundle.js",
38
38
  "test:w3f": "tsx ./test/test-w3f.ts",
@@ -53,14 +53,14 @@
53
53
  "node": ">=18.3.0"
54
54
  },
55
55
  "devDependencies": {
56
- "@biomejs/biome": "^2.4.5",
56
+ "@biomejs/biome": "^2.4.10",
57
57
  "@typeberry/lib": "^0.5.8",
58
58
  "@types/node": "^25.3.3",
59
59
  "assemblyscript": "^0.28.9",
60
- "esbuild": "^0.27.3",
60
+ "esbuild": "^0.28.0",
61
61
  "json-bigint-patch": "^0.0.8",
62
62
  "tsx": "^4.21.0",
63
- "typescript": "^5.9.3"
63
+ "typescript": "^6.0.2"
64
64
  },
65
65
  "files": [
66
66
  "dist/**/*.wasm",