@typeberry/lib 0.5.10-6cb1bd5 → 0.5.10-7338c21

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.
Files changed (71) hide show
  1. package/package.json +1 -1
  2. package/packages/core/codec/encoder.d.ts +1 -1
  3. package/packages/core/codec/encoder.d.ts.map +1 -1
  4. package/packages/core/codec/encoder.js +3 -2
  5. package/packages/core/pvm-interface/pvm.d.ts +2 -0
  6. package/packages/core/pvm-interface/pvm.d.ts.map +1 -1
  7. package/packages/jam/block/work-package.d.ts +7 -7
  8. package/packages/jam/block/work-package.d.ts.map +1 -1
  9. package/packages/jam/block/work-package.js +12 -12
  10. package/packages/jam/executor/pvm-executor.d.ts +9 -2
  11. package/packages/jam/executor/pvm-executor.d.ts.map +1 -1
  12. package/packages/jam/executor/pvm-executor.js +15 -0
  13. package/packages/jam/in-core/externalities/refine.d.ts +18 -8
  14. package/packages/jam/in-core/externalities/refine.d.ts.map +1 -1
  15. package/packages/jam/in-core/externalities/refine.js +86 -7
  16. package/packages/jam/in-core/externalities/refine.test.js +167 -2
  17. package/packages/jam/in-core/in-core.d.ts +7 -22
  18. package/packages/jam/in-core/in-core.d.ts.map +1 -1
  19. package/packages/jam/in-core/in-core.js +16 -186
  20. package/packages/jam/in-core/in-core.test.js +47 -15
  21. package/packages/jam/in-core/is-authorized.d.ts +33 -0
  22. package/packages/jam/in-core/is-authorized.d.ts.map +1 -0
  23. package/packages/jam/in-core/is-authorized.js +72 -0
  24. package/packages/jam/in-core/is-authorized.test.d.ts +2 -0
  25. package/packages/jam/in-core/is-authorized.test.d.ts.map +1 -0
  26. package/packages/jam/in-core/is-authorized.test.js +125 -0
  27. package/packages/jam/in-core/refine.d.ts +34 -0
  28. package/packages/jam/in-core/refine.d.ts.map +1 -0
  29. package/packages/jam/in-core/refine.js +176 -0
  30. package/packages/jam/in-core/refine.test.d.ts +2 -0
  31. package/packages/jam/in-core/refine.test.d.ts.map +1 -0
  32. package/packages/jam/in-core/refine.test.js +6 -0
  33. package/packages/jam/jam-host-calls/accumulate/bless.js +9 -9
  34. package/packages/jam/jam-host-calls/externalities/partial-state.d.ts +1 -1
  35. package/packages/jam/jam-host-calls/externalities/refine-externalities.d.ts +1 -1
  36. package/packages/jam/jam-host-calls/externalities/refine-externalities.d.ts.map +1 -1
  37. package/packages/jam/jam-host-calls/general/fetch.d.ts +164 -103
  38. package/packages/jam/jam-host-calls/general/fetch.d.ts.map +1 -1
  39. package/packages/jam/jam-host-calls/general/fetch.js +117 -23
  40. package/packages/jam/jam-host-calls/general/fetch.test.js +100 -66
  41. package/packages/jam/jamnp-s/protocol/ce-133-work-package-submission.d.ts +2 -2
  42. package/packages/jam/transition/accumulate/accumulate.js +2 -2
  43. package/packages/jam/transition/accumulate/accumulation-result-merge-utils.js +48 -39
  44. package/packages/jam/transition/externalities/accumulate-externalities.d.ts +2 -2
  45. package/packages/jam/transition/externalities/accumulate-externalities.d.ts.map +1 -1
  46. package/packages/jam/transition/externalities/accumulate-externalities.js +20 -7
  47. package/packages/jam/transition/externalities/accumulate-externalities.test.js +74 -4
  48. package/packages/jam/transition/externalities/accumulate-fetch-externalities.d.ts +19 -0
  49. package/packages/jam/transition/externalities/accumulate-fetch-externalities.d.ts.map +1 -0
  50. package/packages/jam/transition/externalities/accumulate-fetch-externalities.js +45 -0
  51. package/packages/jam/transition/externalities/accumulate-fetch-externalities.test.d.ts +2 -0
  52. package/packages/jam/transition/externalities/accumulate-fetch-externalities.test.d.ts.map +1 -0
  53. package/packages/jam/transition/externalities/accumulate-fetch-externalities.test.js +192 -0
  54. package/packages/jam/transition/externalities/fetch-externalities.d.ts +3 -39
  55. package/packages/jam/transition/externalities/fetch-externalities.d.ts.map +1 -1
  56. package/packages/jam/transition/externalities/fetch-externalities.js +2 -88
  57. package/packages/jam/transition/externalities/index.d.ts +3 -0
  58. package/packages/jam/transition/externalities/index.d.ts.map +1 -1
  59. package/packages/jam/transition/externalities/index.js +3 -0
  60. package/packages/jam/transition/externalities/is-authorized-fetch-externalities.d.ts +22 -0
  61. package/packages/jam/transition/externalities/is-authorized-fetch-externalities.d.ts.map +1 -0
  62. package/packages/jam/transition/externalities/is-authorized-fetch-externalities.js +41 -0
  63. package/packages/jam/transition/externalities/refine-fetch-externalities.d.ts +23 -0
  64. package/packages/jam/transition/externalities/refine-fetch-externalities.d.ts.map +1 -0
  65. package/packages/jam/transition/externalities/refine-fetch-externalities.js +56 -0
  66. package/packages/jam/transition/externalities/refine-fetch-externalities.test.d.ts +2 -0
  67. package/packages/jam/transition/externalities/refine-fetch-externalities.test.d.ts.map +1 -0
  68. package/packages/jam/transition/externalities/refine-fetch-externalities.test.js +32 -0
  69. package/packages/jam/transition/externalities/fetch-externalities.test.d.ts +0 -2
  70. package/packages/jam/transition/externalities/fetch-externalities.test.d.ts.map +0 -1
  71. package/packages/jam/transition/externalities/fetch-externalities.test.js +0 -254
@@ -1,14 +1,15 @@
1
1
  import assert from "node:assert";
2
2
  import { describe, it } from "node:test";
3
3
  import { tryAsServiceId } from "#@typeberry/block";
4
- import { BytesBlob } from "#@typeberry/bytes";
4
+ import { Bytes, BytesBlob } from "#@typeberry/bytes";
5
+ import { HASH_SIZE } from "#@typeberry/hash";
5
6
  import { tryAsU64 } from "#@typeberry/numbers";
6
7
  import { HostCallMemory, HostCallRegisters, PvmExecution } from "#@typeberry/pvm-host-calls";
7
8
  import { tryAsGas } from "#@typeberry/pvm-interface";
8
9
  import { gasCounter, MemoryBuilder, tryAsMemoryIndex, tryAsSbrkIndex } from "#@typeberry/pvm-interpreter";
9
10
  import { PAGE_SIZE } from "#@typeberry/pvm-interpreter/memory/memory-consts.js";
10
11
  import { emptyRegistersBuffer } from "../utils.js";
11
- import { Fetch, FetchKind } from "./fetch.js";
12
+ import { Fetch, FetchContext, FetchKind } from "./fetch.js";
12
13
  import { HostCallResult } from "./results.js";
13
14
  describe("Fetch", () => {
14
15
  const IN_OUT_REG = 7;
@@ -16,7 +17,7 @@ describe("Fetch", () => {
16
17
  it("should return PvmExecution.Panic if memory write fails", async () => {
17
18
  const currentServiceId = tryAsServiceId(10_000);
18
19
  const blob = BytesBlob.blobFromNumbers([1, 2, 3]);
19
- const fetchMock = new FetchMock();
20
+ const fetchMock = new RefineFetchMock();
20
21
  fetchMock.constantsResponse = blob;
21
22
  const badOffset = tryAsU64(0xfffff);
22
23
  const registers = new HostCallRegisters(emptyRegistersBuffer());
@@ -33,10 +34,13 @@ describe("Fetch", () => {
33
34
  });
34
35
  it("should write empty result and set IN_OUT_REG to NONE if fetch returns null", async () => {
35
36
  const currentServiceId = tryAsServiceId(10_000);
36
- const fetchMock = new FetchMock();
37
- fetchMock.entropyResponse = null;
37
+ const fetchMock = new RefineFetchMock();
38
+ // oneWorkItem returns null when the work item index has no mock response registered
38
39
  const blob = BytesBlob.blobFromNumbers([]);
39
- const { registers, memory, readBack } = prepareRegsAndMemory(blob, FetchKind.Entropy);
40
+ const { registers, memory, readBack } = prepareRegsAndMemory(blob, FetchKind.OneWorkItem);
41
+ // set work item index to one that has no response → oneWorkItem returns null
42
+ registers.set(11, tryAsU64(999));
43
+ fetchMock.oneWorkItemResponses.set("999", null);
40
44
  const fetch = new Fetch(currentServiceId, fetchMock);
41
45
  const result = await fetch.execute(gas, registers, memory);
42
46
  assert.strictEqual(result, undefined);
@@ -47,7 +51,7 @@ describe("Fetch", () => {
47
51
  it("should write nothing if offset >= blob length", async () => {
48
52
  const currentServiceId = tryAsServiceId(10_000);
49
53
  const blob = BytesBlob.blobFromNumbers([1, 2, 3]);
50
- const fetchMock = new FetchMock();
54
+ const fetchMock = new RefineFetchMock();
51
55
  fetchMock.constantsResponse = blob;
52
56
  const { registers, memory, readBack } = prepareRegsAndMemory(blob, FetchKind.Constants, 5, 2);
53
57
  const fetch = new Fetch(currentServiceId, fetchMock);
@@ -59,7 +63,7 @@ describe("Fetch", () => {
59
63
  it("should clamp offset + length to blob end", async () => {
60
64
  const currentServiceId = tryAsServiceId(10_000);
61
65
  const blob = BytesBlob.blobFromNumbers([9, 8, 7, 6, 5]);
62
- const fetchMock = new FetchMock();
66
+ const fetchMock = new RefineFetchMock();
63
67
  fetchMock.constantsResponse = blob;
64
68
  const { registers, memory, readBack } = prepareRegsAndMemory(blob, FetchKind.Constants, 3, 10);
65
69
  const fetch = new Fetch(currentServiceId, fetchMock);
@@ -71,7 +75,7 @@ describe("Fetch", () => {
71
75
  it("should return NONE and write nothing if fetch kind is unknown", async () => {
72
76
  const currentServiceId = tryAsServiceId(10_000);
73
77
  const blob = BytesBlob.empty();
74
- const fetchMock = new FetchMock();
78
+ const fetchMock = new RefineFetchMock();
75
79
  fetchMock.constantsResponse = blob;
76
80
  const { registers, memory, readBack } = prepareRegsAndMemory(blob, FetchKind.Constants);
77
81
  registers.set(10, tryAsU64(999));
@@ -84,7 +88,7 @@ describe("Fetch", () => {
84
88
  it("should fetch constants and write result to memory", async () => {
85
89
  const currentServiceId = tryAsServiceId(10_000);
86
90
  const blob = BytesBlob.blobFromNumbers([1, 2, 3, 4, 5]);
87
- const fetchMock = new FetchMock();
91
+ const fetchMock = new RefineFetchMock();
88
92
  fetchMock.constantsResponse = blob;
89
93
  const { registers, memory, readBack, expectedLength } = prepareRegsAndMemory(blob, FetchKind.Constants);
90
94
  const fetch = new Fetch(currentServiceId, fetchMock);
@@ -95,8 +99,8 @@ describe("Fetch", () => {
95
99
  });
96
100
  it("should fetch entropy and write result to memory", async () => {
97
101
  const currentServiceId = tryAsServiceId(10_000);
98
- const blob = BytesBlob.blobFromNumbers([10, 20, 30, 40]);
99
- const fetchMock = new FetchMock();
102
+ const blob = Bytes.fill(HASH_SIZE, 10).asOpaque();
103
+ const fetchMock = new RefineFetchMock();
100
104
  fetchMock.entropyResponse = blob;
101
105
  const { registers, memory, readBack, expectedLength } = prepareRegsAndMemory(blob, FetchKind.Entropy);
102
106
  const fetch = new Fetch(currentServiceId, fetchMock);
@@ -108,7 +112,7 @@ describe("Fetch", () => {
108
112
  it("should fetch authorizer trace and write result to memory", async () => {
109
113
  const currentServiceId = tryAsServiceId(10_000);
110
114
  const blob = BytesBlob.blobFromNumbers([9, 9, 9]);
111
- const fetchMock = new FetchMock();
115
+ const fetchMock = new RefineFetchMock();
112
116
  fetchMock.authorizerTraceResponse = blob;
113
117
  const { registers, memory, readBack, expectedLength } = prepareRegsAndMemory(blob, FetchKind.AuthorizerTrace);
114
118
  const fetch = new Fetch(currentServiceId, fetchMock);
@@ -120,7 +124,7 @@ describe("Fetch", () => {
120
124
  it("should fetch other work item extrinsics and write result to memory", async () => {
121
125
  const currentServiceId = tryAsServiceId(10_000);
122
126
  const blob = BytesBlob.blobFromNumbers([42, 43, 44]);
123
- const fetchMock = new FetchMock();
127
+ const fetchMock = new RefineFetchMock();
124
128
  const workItem = tryAsU64(123);
125
129
  const index = tryAsU64(7);
126
130
  const key = `${workItem}:${index}`;
@@ -138,7 +142,7 @@ describe("Fetch", () => {
138
142
  it("should fetch my extrinsics and write result to memory", async () => {
139
143
  const currentServiceId = tryAsServiceId(10_000);
140
144
  const blob = BytesBlob.blobFromNumbers([11, 12, 13]);
141
- const fetchMock = new FetchMock();
145
+ const fetchMock = new RefineFetchMock();
142
146
  const index = tryAsU64(5);
143
147
  const key = `null:${index}`;
144
148
  fetchMock.workItemExtrinsicResponses.set(key, blob);
@@ -154,7 +158,7 @@ describe("Fetch", () => {
154
158
  it("should fetch other work item imports and write result to memory", async () => {
155
159
  const currentServiceId = tryAsServiceId(10_000);
156
160
  const blob = BytesBlob.blobFromNumbers([21, 22, 23]);
157
- const fetchMock = new FetchMock();
161
+ const fetchMock = new RefineFetchMock();
158
162
  const workItem = tryAsU64(42);
159
163
  const index = tryAsU64(3);
160
164
  const key = `${workItem}:${index}`;
@@ -172,7 +176,7 @@ describe("Fetch", () => {
172
176
  it("should fetch my imports and write result to memory", async () => {
173
177
  const currentServiceId = tryAsServiceId(10_000);
174
178
  const blob = BytesBlob.blobFromNumbers([31, 32, 33]);
175
- const fetchMock = new FetchMock();
179
+ const fetchMock = new RefineFetchMock();
176
180
  const index = tryAsU64(8);
177
181
  const key = `null:${index}`;
178
182
  fetchMock.workItemImportResponses.set(key, blob);
@@ -188,7 +192,7 @@ describe("Fetch", () => {
188
192
  it("should fetch work package and write result to memory", async () => {
189
193
  const currentServiceId = tryAsServiceId(10_000);
190
194
  const blob = BytesBlob.blobFromNumbers([100, 101, 102]);
191
- const fetchMock = new FetchMock();
195
+ const fetchMock = new RefineFetchMock();
192
196
  fetchMock.workPackageResponse = blob;
193
197
  const { registers, memory, readBack, expectedLength } = prepareRegsAndMemory(blob, FetchKind.WorkPackage);
194
198
  const fetch = new Fetch(currentServiceId, fetchMock);
@@ -200,9 +204,9 @@ describe("Fetch", () => {
200
204
  it("should fetch authorizer and write result to memory", async () => {
201
205
  const currentServiceId = tryAsServiceId(10_000);
202
206
  const blob = BytesBlob.blobFromNumbers([201, 202, 203]);
203
- const fetchMock = new FetchMock();
207
+ const fetchMock = new RefineFetchMock();
204
208
  fetchMock.authorizerResponse = blob;
205
- const { registers, memory, readBack, expectedLength } = prepareRegsAndMemory(blob, FetchKind.Authorizer);
209
+ const { registers, memory, readBack, expectedLength } = prepareRegsAndMemory(blob, FetchKind.AuthConfiguration);
206
210
  const fetch = new Fetch(currentServiceId, fetchMock);
207
211
  const result = await fetch.execute(gas, registers, memory);
208
212
  assert.strictEqual(result, undefined);
@@ -212,9 +216,9 @@ describe("Fetch", () => {
212
216
  it("should fetch authorization token and write result to memory", async () => {
213
217
  const currentServiceId = tryAsServiceId(10_000);
214
218
  const blob = BytesBlob.blobFromNumbers([210, 211, 212]);
215
- const fetchMock = new FetchMock();
219
+ const fetchMock = new RefineFetchMock();
216
220
  fetchMock.authorizationTokenResponse = blob;
217
- const { registers, memory, readBack, expectedLength } = prepareRegsAndMemory(blob, FetchKind.AuthorizationToken);
221
+ const { registers, memory, readBack, expectedLength } = prepareRegsAndMemory(blob, FetchKind.AuthToken);
218
222
  const fetch = new Fetch(currentServiceId, fetchMock);
219
223
  const result = await fetch.execute(gas, registers, memory);
220
224
  assert.strictEqual(result, undefined);
@@ -224,7 +228,7 @@ describe("Fetch", () => {
224
228
  it("should fetch refine context and write result to memory", async () => {
225
229
  const currentServiceId = tryAsServiceId(10_000);
226
230
  const blob = BytesBlob.blobFromNumbers([88, 89, 90]);
227
- const fetchMock = new FetchMock();
231
+ const fetchMock = new RefineFetchMock();
228
232
  fetchMock.refineContextResponse = blob;
229
233
  const { registers, memory, readBack, expectedLength } = prepareRegsAndMemory(blob, FetchKind.RefineContext);
230
234
  const fetch = new Fetch(currentServiceId, fetchMock);
@@ -236,7 +240,7 @@ describe("Fetch", () => {
236
240
  it("should fetch all work items and write result to memory", async () => {
237
241
  const currentServiceId = tryAsServiceId(10_000);
238
242
  const blob = BytesBlob.blobFromNumbers([70, 71, 72]);
239
- const fetchMock = new FetchMock();
243
+ const fetchMock = new RefineFetchMock();
240
244
  fetchMock.allWorkItemsResponse = blob;
241
245
  const { registers, memory, readBack, expectedLength } = prepareRegsAndMemory(blob, FetchKind.AllWorkItems);
242
246
  const fetch = new Fetch(currentServiceId, fetchMock);
@@ -248,7 +252,7 @@ describe("Fetch", () => {
248
252
  it("should fetch one work item and write result to memory", async () => {
249
253
  const currentServiceId = tryAsServiceId(10_000);
250
254
  const blob = BytesBlob.blobFromNumbers([33, 34, 35]);
251
- const fetchMock = new FetchMock();
255
+ const fetchMock = new RefineFetchMock();
252
256
  const workItem = tryAsU64(55);
253
257
  fetchMock.oneWorkItemResponses.set(workItem.toString(), blob);
254
258
  const { registers, memory, readBack, expectedLength } = prepareRegsAndMemory(blob, FetchKind.OneWorkItem);
@@ -263,7 +267,7 @@ describe("Fetch", () => {
263
267
  it("should fetch work item payload and write result to memory", async () => {
264
268
  const currentServiceId = tryAsServiceId(10_000);
265
269
  const blob = BytesBlob.blobFromNumbers([60, 61, 62]);
266
- const fetchMock = new FetchMock();
270
+ const fetchMock = new RefineFetchMock();
267
271
  const workItem = tryAsU64(77);
268
272
  fetchMock.workItemPayloadResponses.set(workItem.toString(), blob);
269
273
  const { registers, memory, readBack, expectedLength } = prepareRegsAndMemory(blob, FetchKind.WorkItemPayload);
@@ -278,8 +282,8 @@ describe("Fetch", () => {
278
282
  it("should fetch all transfers and operands and write result to memory", async () => {
279
283
  const currentServiceId = tryAsServiceId(10_000);
280
284
  const blob = BytesBlob.blobFromNumbers([101, 102, 103]);
281
- const fetchMock = new FetchMock();
282
- fetchMock.allTransfersAndOperandsResponses = blob;
285
+ const fetchMock = new AccumulateFetchMock();
286
+ fetchMock.allTransfersAndOperandsResponse = blob;
283
287
  const { registers, memory, readBack, expectedLength } = prepareRegsAndMemory(blob, FetchKind.AllTransfersAndOperands);
284
288
  const fetch = new Fetch(currentServiceId, fetchMock);
285
289
  const result = await fetch.execute(gas, registers, memory);
@@ -290,7 +294,7 @@ describe("Fetch", () => {
290
294
  it("should fetch one operand or transfer and write result to memory", async () => {
291
295
  const currentServiceId = tryAsServiceId(10_000);
292
296
  const blob = BytesBlob.blobFromNumbers([115, 116, 117]);
293
- const fetchMock = new FetchMock();
297
+ const fetchMock = new AccumulateFetchMock();
294
298
  const index = tryAsU64(9);
295
299
  fetchMock.oneTransferOrOperandResponses.set(index.toString(), blob);
296
300
  const { registers, memory, readBack, expectedLength } = prepareRegsAndMemory(blob, FetchKind.OneTransferOrOperand);
@@ -302,6 +306,43 @@ describe("Fetch", () => {
302
306
  assert.deepStrictEqual(readBack(), blob.raw);
303
307
  assert.deepStrictEqual(fetchMock.oneTransferOrOperandData, [[index]]);
304
308
  });
309
+ it("should return NONE for refine-only kinds in accumulate context", async () => {
310
+ const currentServiceId = tryAsServiceId(10_000);
311
+ const fetchMock = new AccumulateFetchMock();
312
+ const blob = BytesBlob.empty();
313
+ for (const kind of [
314
+ FetchKind.AuthorizerTrace,
315
+ FetchKind.OtherWorkItemExtrinsics,
316
+ FetchKind.MyExtrinsics,
317
+ FetchKind.OtherWorkItemImports,
318
+ FetchKind.MyImports,
319
+ FetchKind.WorkPackage,
320
+ FetchKind.AuthConfiguration,
321
+ FetchKind.AuthToken,
322
+ FetchKind.RefineContext,
323
+ FetchKind.AllWorkItems,
324
+ FetchKind.OneWorkItem,
325
+ FetchKind.WorkItemPayload,
326
+ ]) {
327
+ const { registers, memory } = prepareRegsAndMemory(blob, kind);
328
+ const fetch = new Fetch(currentServiceId, fetchMock);
329
+ const result = await fetch.execute(gas, registers, memory);
330
+ assert.strictEqual(result, undefined, `Expected undefined for kind ${kind}`);
331
+ assert.strictEqual(registers.get(IN_OUT_REG), HostCallResult.NONE, `Expected NONE for kind ${kind}`);
332
+ }
333
+ });
334
+ it("should return NONE for accumulate-only kinds in refine context", async () => {
335
+ const currentServiceId = tryAsServiceId(10_000);
336
+ const fetchMock = new RefineFetchMock();
337
+ const blob = BytesBlob.empty();
338
+ for (const kind of [FetchKind.AllTransfersAndOperands, FetchKind.OneTransferOrOperand]) {
339
+ const { registers, memory } = prepareRegsAndMemory(blob, kind);
340
+ const fetch = new Fetch(currentServiceId, fetchMock);
341
+ const result = await fetch.execute(gas, registers, memory);
342
+ assert.strictEqual(result, undefined, `Expected undefined for kind ${kind}`);
343
+ assert.strictEqual(registers.get(IN_OUT_REG), HostCallResult.NONE, `Expected NONE for kind ${kind}`);
344
+ }
345
+ });
305
346
  function prepareRegsAndMemory(blob, fetchKind, offset = 0, length = blob.length) {
306
347
  const pageStart = 2 ** 16;
307
348
  const memOffset = tryAsU64(pageStart + 1234);
@@ -327,32 +368,24 @@ describe("Fetch", () => {
327
368
  };
328
369
  }
329
370
  });
330
- class FetchMock {
371
+ class RefineFetchMock {
372
+ context = FetchContext.Refine;
331
373
  workItemExtrinsicData = [];
332
374
  workItemImportData = [];
333
375
  oneWorkItemData = [];
334
376
  workItemPayloadData = [];
335
- oneOperandData = [];
336
- oneTransferData = [];
337
- oneTransferOrOperandData = [];
338
377
  constantsResponse = null;
339
378
  entropyResponse = null;
340
- authorizerTraceResponse = null;
379
+ authorizerTraceResponse = BytesBlob.empty();
341
380
  workItemExtrinsicResponses = new Map();
342
381
  workItemImportResponses = new Map();
343
- workPackageResponse = null;
344
- authorizerResponse = null;
345
- authorizationTokenResponse = null;
346
- refineContextResponse = null;
347
- allWorkItemsResponse = null;
382
+ workPackageResponse = BytesBlob.empty();
383
+ authorizerResponse = BytesBlob.empty();
384
+ authorizationTokenResponse = BytesBlob.empty();
385
+ refineContextResponse = BytesBlob.empty();
386
+ allWorkItemsResponse = BytesBlob.empty();
348
387
  oneWorkItemResponses = new Map();
349
388
  workItemPayloadResponses = new Map();
350
- allOperandsResponse = null;
351
- oneOperandResponses = new Map();
352
- allTransfersResponse = null;
353
- oneTransferResponses = new Map();
354
- allTransfersAndOperandsResponses = null;
355
- oneTransferOrOperandResponses = new Map();
356
389
  constants() {
357
390
  if (this.constantsResponse === null) {
358
391
  throw new Error("Unexpected call to constants.");
@@ -360,6 +393,9 @@ class FetchMock {
360
393
  return this.constantsResponse;
361
394
  }
362
395
  entropy() {
396
+ if (this.entropyResponse === null) {
397
+ throw new Error("Unexpected call to entropy.");
398
+ }
363
399
  return this.entropyResponse;
364
400
  }
365
401
  authorizerTrace() {
@@ -384,10 +420,10 @@ class FetchMock {
384
420
  workPackage() {
385
421
  return this.workPackageResponse;
386
422
  }
387
- authorizer() {
423
+ authConfiguration() {
388
424
  return this.authorizerResponse;
389
425
  }
390
- authorizationToken() {
426
+ authToken() {
391
427
  return this.authorizationTokenResponse;
392
428
  }
393
429
  refineContext() {
@@ -412,30 +448,28 @@ class FetchMock {
412
448
  }
413
449
  return this.workItemPayloadResponses.get(key) ?? null;
414
450
  }
415
- allOperands() {
416
- return this.allOperandsResponse;
417
- }
418
- oneOperand(operandIndex) {
419
- this.oneOperandData.push([operandIndex]);
420
- const key = operandIndex.toString();
421
- if (!this.oneOperandResponses.has(key)) {
422
- throw new Error(`Missing mock response for oneOperand(${key})`);
451
+ }
452
+ class AccumulateFetchMock {
453
+ context = FetchContext.Accumulate;
454
+ oneTransferOrOperandData = [];
455
+ constantsResponse = null;
456
+ entropyResponse = null;
457
+ allTransfersAndOperandsResponse = null;
458
+ oneTransferOrOperandResponses = new Map();
459
+ constants() {
460
+ if (this.constantsResponse === null) {
461
+ throw new Error("Unexpected call to constants.");
423
462
  }
424
- return this.oneOperandResponses.get(key) ?? null;
425
- }
426
- allTransfers() {
427
- return this.allTransfersResponse;
463
+ return this.constantsResponse;
428
464
  }
429
- oneTransfer(transferIndex) {
430
- this.oneTransferData.push([transferIndex]);
431
- const key = transferIndex.toString();
432
- if (!this.oneTransferResponses.has(key)) {
433
- throw new Error(`Missing mock response for oneTransfer(${key})`);
465
+ entropy() {
466
+ if (this.entropyResponse === null) {
467
+ throw new Error("Unexpected call to entropy.");
434
468
  }
435
- return this.oneTransferResponses.get(key) ?? null;
469
+ return this.entropyResponse;
436
470
  }
437
471
  allTransfersAndOperands() {
438
- return this.allTransfersAndOperandsResponses;
472
+ return this.allTransfersAndOperandsResponse;
439
473
  }
440
474
  oneTransferOrOperand(index) {
441
475
  this.oneTransferOrOperandData.push([index]);
@@ -29,8 +29,8 @@ export declare class CoreWorkPackage extends WithDebug {
29
29
  lookupAnchorSlot: import("@typeberry/codec").Descriptor<number & import("@typeberry/numbers").WithBytesRepresentation<4> & import("@typeberry/utils").WithOpaque<"TimeSlot[u32]">, import("@typeberry/bytes").Bytes<4>>;
30
30
  prerequisites: import("@typeberry/codec").Descriptor<(import("@typeberry/bytes").Bytes<32> & import("@typeberry/utils").WithOpaque<"WorkPackageHash">)[], import("@typeberry/codec").SequenceView<import("@typeberry/bytes").Bytes<32> & import("@typeberry/utils").WithOpaque<"WorkPackageHash">, import("@typeberry/bytes").Bytes<32>>>;
31
31
  }>>;
32
- authorization: import("@typeberry/codec").Descriptor<BytesBlob, BytesBlob>;
33
- parametrization: import("@typeberry/codec").Descriptor<BytesBlob, BytesBlob>;
32
+ authToken: import("@typeberry/codec").Descriptor<BytesBlob, BytesBlob>;
33
+ authConfiguration: import("@typeberry/codec").Descriptor<BytesBlob, BytesBlob>;
34
34
  items: import("@typeberry/codec").Descriptor<import("@typeberry/collections").FixedSizeArray<import("@typeberry/block").WorkItem, import("@typeberry/numbers").U8>, import("@typeberry/codec").SequenceView<import("@typeberry/block").WorkItem, import("@typeberry/codec").ViewOf<import("@typeberry/block").WorkItem, {
35
35
  service: import("@typeberry/codec").Descriptor<number & import("@typeberry/numbers").WithBytesRepresentation<4> & import("@typeberry/utils").WithOpaque<"ServiceId[u32]">, import("@typeberry/bytes").Bytes<4>>;
36
36
  codeHash: import("@typeberry/codec").Descriptor<import("@typeberry/bytes").Bytes<32> & import("@typeberry/utils").WithOpaque<"CodeHash">, import("@typeberry/bytes").Bytes<32>>;
@@ -11,7 +11,7 @@ import { MAX_VALUE_U64, sumU64, tryAsU32 } from "#@typeberry/numbers";
11
11
  import { accumulationOutputComparator, hashComparator, ServiceAccountInfo, tryAsPerCore, } from "#@typeberry/state";
12
12
  import { assertEmpty, Compatibility, GpVersion, Result, TestSuite } from "#@typeberry/utils";
13
13
  import { AccumulateExternalities } from "../externalities/accumulate-externalities.js";
14
- import { FetchExternalities } from "../externalities/index.js";
14
+ import { AccumulateFetchExternalities } from "../externalities/accumulate-fetch-externalities.js";
15
15
  import { AccumulateData } from "./accumulate-data.js";
16
16
  import { AccumulateQueue, pruneQueue } from "./accumulate-queue.js";
17
17
  import { GAS_TO_INVOKE_WORK_REPORT, } from "./accumulate-state.js";
@@ -86,7 +86,7 @@ export class Accumulate {
86
86
  }
87
87
  const nextServiceId = generateNextServiceId({ serviceId, entropy, timeslot: slot }, this.chainSpec, this.blake2b);
88
88
  const partialState = new AccumulateExternalities(this.chainSpec, this.blake2b, updatedState, serviceId, nextServiceId, slot);
89
- const fetchExternalities = FetchExternalities.createForAccumulate({ entropy, transfers, operands }, this.chainSpec);
89
+ const fetchExternalities = new AccumulateFetchExternalities(entropy, transfers, operands, this.chainSpec);
90
90
  const externalities = {
91
91
  partialState,
92
92
  serviceExternalities: partialState,
@@ -44,47 +44,56 @@ function mergePrivilegedServices(mergeContext, [serviceId, { stateUpdate }]) {
44
44
  const currentDelegator = currentPrivilegedServices.delegator;
45
45
  const currentAssigners = currentPrivilegedServices.assigners;
46
46
  const { privilegedServices } = stateUpdate;
47
- if (privilegedServices !== null) {
48
- if (outputState.privilegedServices === null) {
49
- outputState.privilegedServices = PrivilegedServices.create({
50
- ...currentPrivilegedServices,
51
- });
52
- }
53
- if (serviceId === currentManager) {
54
- outputState.privilegedServices = PrivilegedServices.create({
55
- ...privilegedServices,
56
- });
57
- }
58
- if (serviceId === currentRegistrar) {
59
- const newRegistrar = updatePrivilegedService(currentPrivilegedServices.registrar, privilegedServicesUpdatedByManager.registrar, privilegedServices.registrar);
60
- outputState.privilegedServices = PrivilegedServices.create({
61
- ...outputState.privilegedServices,
62
- registrar: newRegistrar,
63
- });
64
- }
65
- if (serviceId === currentDelegator) {
66
- const newDelegator = updatePrivilegedService(currentPrivilegedServices.delegator, privilegedServicesUpdatedByManager.delegator, privilegedServices.delegator);
67
- outputState.privilegedServices = PrivilegedServices.create({
68
- ...outputState.privilegedServices,
69
- delegator: newDelegator,
70
- });
71
- }
72
- let shouldUpdateAssigners = false;
73
- const newAssigners = currentAssigners.map((currentAssigner, coreIndex) => {
74
- if (serviceId === currentAssigner) {
75
- const newAssigner = updatePrivilegedService(currentPrivilegedServices.assigners[coreIndex], privilegedServicesUpdatedByManager.assigners[coreIndex], privilegedServices.assigners[coreIndex]);
76
- shouldUpdateAssigners = shouldUpdateAssigners || newAssigner !== currentAssigner;
77
- return newAssigner;
78
- }
79
- return currentAssigner;
47
+ if (privilegedServices === null) {
48
+ return;
49
+ }
50
+ // initial value (ignore the update, because it might not be authorized)
51
+ if (outputState.privilegedServices === null) {
52
+ outputState.privilegedServices = PrivilegedServices.create({
53
+ ...currentPrivilegedServices,
54
+ });
55
+ }
56
+ // manager can override everything and it always takes precedence over
57
+ // everything else
58
+ if (serviceId === currentManager) {
59
+ outputState.privilegedServices = PrivilegedServices.create({
60
+ ...privilegedServices,
61
+ });
62
+ }
63
+ // current registrar can transfer out it's permissions, but only if
64
+ // it wasn't overwritten by manager in current run
65
+ if (serviceId === currentRegistrar) {
66
+ const newRegistrar = updatePrivilegedService(currentPrivilegedServices.registrar, privilegedServicesUpdatedByManager.registrar, privilegedServices.registrar);
67
+ outputState.privilegedServices = PrivilegedServices.create({
68
+ ...outputState.privilegedServices,
69
+ registrar: newRegistrar,
80
70
  });
81
- if (shouldUpdateAssigners) {
82
- const newAssignersPerCore = tryAsPerCore(newAssigners, chainSpec);
83
- outputState.privilegedServices = PrivilegedServices.create({
84
- ...outputState.privilegedServices,
85
- assigners: newAssignersPerCore,
86
- });
71
+ }
72
+ // current delegator can transfer out it's permissions, but only if
73
+ // it wasn't overwritten by manager in current run
74
+ if (serviceId === currentDelegator) {
75
+ const newDelegator = updatePrivilegedService(currentPrivilegedServices.delegator, privilegedServicesUpdatedByManager.delegator, privilegedServices.delegator);
76
+ outputState.privilegedServices = PrivilegedServices.create({
77
+ ...outputState.privilegedServices,
78
+ delegator: newDelegator,
79
+ });
80
+ }
81
+ let shouldUpdateAssigners = false;
82
+ // same with assigners - they are free to transfer out their core
83
+ const newAssigners = currentAssigners.map((currentAssigner, coreIndex) => {
84
+ if (serviceId === currentAssigner) {
85
+ const newAssigner = updatePrivilegedService(currentPrivilegedServices.assigners[coreIndex], privilegedServicesUpdatedByManager.assigners[coreIndex], privilegedServices.assigners[coreIndex]);
86
+ shouldUpdateAssigners = shouldUpdateAssigners || newAssigner !== currentAssigner;
87
+ return newAssigner;
87
88
  }
89
+ return currentAssigner;
90
+ });
91
+ if (shouldUpdateAssigners) {
92
+ const newAssignersPerCore = tryAsPerCore(newAssigners, chainSpec);
93
+ outputState.privilegedServices = PrivilegedServices.create({
94
+ ...outputState.privilegedServices,
95
+ assigners: newAssignersPerCore,
96
+ });
88
97
  }
89
98
  }
90
99
  function mergeValidatorsData(mergeContext, [serviceId, { stateUpdate }]) {
@@ -2,7 +2,7 @@ import { type CodeHash, type CoreIndex, type PerValidator, type ServiceGas, type
2
2
  import type { PreimageHash } from "#@typeberry/block/preimage.js";
3
3
  import type { AuthorizerHash } from "#@typeberry/block/refine-context.js";
4
4
  import { Bytes, type BytesBlob } from "#@typeberry/bytes";
5
- import type { FixedSizeArray } from "#@typeberry/collections";
5
+ import { type FixedSizeArray } from "#@typeberry/collections";
6
6
  import type { ChainSpec } from "#@typeberry/config";
7
7
  import { type Blake2b, type OpaqueHash } from "#@typeberry/hash";
8
8
  import { AccumulationStateUpdate, EjectError, ForgetPreimageError, type general, NewServiceError, type PartiallyUpdatedState, type PartialState, type PreimageStatus, ProvidePreimageError, RequestPreimageError, type TRANSFER_MEMO_BYTES, TransferError, UnprivilegedError, UpdatePrivilegesError } from "#@typeberry/jam-host-calls";
@@ -64,7 +64,7 @@ export declare class AccumulateExternalities implements PartialState, general.Ac
64
64
  upgradeService(codeHash: CodeHash, gas: U64, allowance: U64): void;
65
65
  updateValidatorsData(validatorsData: PerValidator<ValidatorData>): Result<OK, UnprivilegedError>;
66
66
  checkpoint(): void;
67
- updateAuthorizationQueue(coreIndex: CoreIndex, authQueue: FixedSizeArray<AuthorizerHash, AUTHORIZATION_QUEUE_SIZE>, assigners: ServiceId | null): Result<OK, UpdatePrivilegesError>;
67
+ updateAuthorizationQueue(coreIndex: CoreIndex, authQueue: FixedSizeArray<AuthorizerHash, AUTHORIZATION_QUEUE_SIZE>, newAssigner: ServiceId | null): Result<OK, UpdatePrivilegesError>;
68
68
  updatePrivilegedServices(manager: ServiceId | null, assigners: PerCore<ServiceId>, delegator: ServiceId | null, registrar: ServiceId | null, autoAccumulateServices: Map<ServiceId, ServiceGas>): Result<OK, UpdatePrivilegesError>;
69
69
  yield(hash: OpaqueHash): void;
70
70
  providePreimage(serviceId: ServiceId | null, preimage: BytesBlob): Result<OK, ProvidePreimageError>;
@@ -1 +1 @@
1
- {"version":3,"file":"accumulate-externalities.d.ts","sourceRoot":"","sources":["../../../../../../packages/jam/transition/externalities/accumulate-externalities.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"accumulate-externalities.d.ts","sourceRoot":"","sources":["../../../../../../packages/jam/transition/externalities/accumulate-externalities.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { tryAsServiceGas, tryAsServiceId, tryAsTimeSlot, } from "#@typeberry/block";
2
2
  import { MIN_PUBLIC_SERVICE_INDEX } from "#@typeberry/block/gp-constants.js";
3
3
  import { Bytes } from "#@typeberry/bytes";
4
+ import { asKnownSize } from "#@typeberry/collections";
4
5
  import { HASH_SIZE } from "#@typeberry/hash";
5
6
  import { AccumulationStateUpdate, clampU64ToU32, EjectError, ForgetPreimageError, NewServiceError, PendingTransfer, PreimageStatusKind, ProvidePreimageError, RequestPreimageError, slotsToPreimageStatus, TransferError, UnprivilegedError, UpdatePrivilegesError, writeServiceIdAsLeBytes, } from "#@typeberry/jam-host-calls";
6
7
  import { Logger } from "#@typeberry/logger";
@@ -354,19 +355,31 @@ export class AccumulateExternalities {
354
355
  /** https://graypaper.fluffylabs.dev/#/9a08063/362202362202?v=0.6.6 */
355
356
  this.checkpointedState = AccumulationStateUpdate.copyFrom(this.updatedState.stateUpdate);
356
357
  }
357
- updateAuthorizationQueue(coreIndex, authQueue, assigners) {
358
+ updateAuthorizationQueue(coreIndex, authQueue, newAssigner) {
358
359
  /** https://graypaper.fluffylabs.dev/#/7e6ff6a/36a40136a401?v=0.6.7 */
359
360
  // NOTE `coreIndex` is already verified in the HC, so this is infallible.
360
- const currentAssigners = this.updatedState.getPrivilegedServices().assigners[coreIndex];
361
- if (currentAssigners !== this.currentServiceId) {
362
- logger.trace `Current service id (${this.currentServiceId}) is not an auth manager of core ${coreIndex} (expected: ${currentAssigners}) and cannot update authorization queue.`;
363
- return Result.error(UpdatePrivilegesError.UnprivilegedService, () => `Service ${this.currentServiceId} not assigner for core ${coreIndex} (expected: ${currentAssigners})`);
364
- }
365
- if (assigners === null) {
361
+ const privilegedServices = this.updatedState.getPrivilegedServices();
362
+ const currentAssigners = privilegedServices.assigners;
363
+ const assigner = currentAssigners[coreIndex];
364
+ if (assigner !== this.currentServiceId) {
365
+ logger.trace `Current service id (${this.currentServiceId}) is not an auth manager of core ${coreIndex} (expected: ${assigner}) and cannot update authorization queue.`;
366
+ return Result.error(UpdatePrivilegesError.UnprivilegedService, () => `Service ${this.currentServiceId} not assigner for core ${coreIndex} (expected: ${assigner})`);
367
+ }
368
+ if (newAssigner === null) {
366
369
  logger.trace `The new auth manager is not a valid service id.`;
367
370
  return Result.error(UpdatePrivilegesError.InvalidServiceId, () => `New auth manager is null for core ${coreIndex}`);
368
371
  }
372
+ // update the authorization queue
369
373
  this.updatedState.stateUpdate.authorizationQueues.set(coreIndex, authQueue);
374
+ // move permissions to the new assigner
375
+ const assigners = currentAssigners.slice();
376
+ assigners[coreIndex] = newAssigner;
377
+ this.updatedState.stateUpdate.privilegedServices = PrivilegedServices.create({
378
+ ...privilegedServices,
379
+ // since coreindex is validated, we do not alter the size,
380
+ // hence it's safe to convert back
381
+ assigners: asKnownSize(assigners),
382
+ });
370
383
  return Result.ok(OK);
371
384
  }
372
385
  updatePrivilegedServices(manager, assigners, delegator, registrar, autoAccumulateServices) {