@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.
- package/package.json +1 -1
- package/packages/core/codec/encoder.d.ts +1 -1
- package/packages/core/codec/encoder.d.ts.map +1 -1
- package/packages/core/codec/encoder.js +3 -2
- package/packages/core/pvm-interface/pvm.d.ts +2 -0
- package/packages/core/pvm-interface/pvm.d.ts.map +1 -1
- package/packages/jam/block/work-package.d.ts +7 -7
- package/packages/jam/block/work-package.d.ts.map +1 -1
- package/packages/jam/block/work-package.js +12 -12
- package/packages/jam/executor/pvm-executor.d.ts +9 -2
- package/packages/jam/executor/pvm-executor.d.ts.map +1 -1
- package/packages/jam/executor/pvm-executor.js +15 -0
- package/packages/jam/in-core/externalities/refine.d.ts +18 -8
- package/packages/jam/in-core/externalities/refine.d.ts.map +1 -1
- package/packages/jam/in-core/externalities/refine.js +86 -7
- package/packages/jam/in-core/externalities/refine.test.js +167 -2
- package/packages/jam/in-core/in-core.d.ts +7 -22
- package/packages/jam/in-core/in-core.d.ts.map +1 -1
- package/packages/jam/in-core/in-core.js +16 -186
- package/packages/jam/in-core/in-core.test.js +47 -15
- package/packages/jam/in-core/is-authorized.d.ts +33 -0
- package/packages/jam/in-core/is-authorized.d.ts.map +1 -0
- package/packages/jam/in-core/is-authorized.js +72 -0
- package/packages/jam/in-core/is-authorized.test.d.ts +2 -0
- package/packages/jam/in-core/is-authorized.test.d.ts.map +1 -0
- package/packages/jam/in-core/is-authorized.test.js +125 -0
- package/packages/jam/in-core/refine.d.ts +34 -0
- package/packages/jam/in-core/refine.d.ts.map +1 -0
- package/packages/jam/in-core/refine.js +176 -0
- package/packages/jam/in-core/refine.test.d.ts +2 -0
- package/packages/jam/in-core/refine.test.d.ts.map +1 -0
- package/packages/jam/in-core/refine.test.js +6 -0
- package/packages/jam/jam-host-calls/accumulate/bless.js +9 -9
- package/packages/jam/jam-host-calls/externalities/partial-state.d.ts +1 -1
- package/packages/jam/jam-host-calls/externalities/refine-externalities.d.ts +1 -1
- package/packages/jam/jam-host-calls/externalities/refine-externalities.d.ts.map +1 -1
- package/packages/jam/jam-host-calls/general/fetch.d.ts +164 -103
- package/packages/jam/jam-host-calls/general/fetch.d.ts.map +1 -1
- package/packages/jam/jam-host-calls/general/fetch.js +117 -23
- package/packages/jam/jam-host-calls/general/fetch.test.js +100 -66
- package/packages/jam/jamnp-s/protocol/ce-133-work-package-submission.d.ts +2 -2
- package/packages/jam/transition/accumulate/accumulate.js +2 -2
- package/packages/jam/transition/accumulate/accumulation-result-merge-utils.js +48 -39
- package/packages/jam/transition/externalities/accumulate-externalities.d.ts +2 -2
- package/packages/jam/transition/externalities/accumulate-externalities.d.ts.map +1 -1
- package/packages/jam/transition/externalities/accumulate-externalities.js +20 -7
- package/packages/jam/transition/externalities/accumulate-externalities.test.js +74 -4
- package/packages/jam/transition/externalities/accumulate-fetch-externalities.d.ts +19 -0
- package/packages/jam/transition/externalities/accumulate-fetch-externalities.d.ts.map +1 -0
- package/packages/jam/transition/externalities/accumulate-fetch-externalities.js +45 -0
- package/packages/jam/transition/externalities/accumulate-fetch-externalities.test.d.ts +2 -0
- package/packages/jam/transition/externalities/accumulate-fetch-externalities.test.d.ts.map +1 -0
- package/packages/jam/transition/externalities/accumulate-fetch-externalities.test.js +192 -0
- package/packages/jam/transition/externalities/fetch-externalities.d.ts +3 -39
- package/packages/jam/transition/externalities/fetch-externalities.d.ts.map +1 -1
- package/packages/jam/transition/externalities/fetch-externalities.js +2 -88
- package/packages/jam/transition/externalities/index.d.ts +3 -0
- package/packages/jam/transition/externalities/index.d.ts.map +1 -1
- package/packages/jam/transition/externalities/index.js +3 -0
- package/packages/jam/transition/externalities/is-authorized-fetch-externalities.d.ts +22 -0
- package/packages/jam/transition/externalities/is-authorized-fetch-externalities.d.ts.map +1 -0
- package/packages/jam/transition/externalities/is-authorized-fetch-externalities.js +41 -0
- package/packages/jam/transition/externalities/refine-fetch-externalities.d.ts +23 -0
- package/packages/jam/transition/externalities/refine-fetch-externalities.d.ts.map +1 -0
- package/packages/jam/transition/externalities/refine-fetch-externalities.js +56 -0
- package/packages/jam/transition/externalities/refine-fetch-externalities.test.d.ts +2 -0
- package/packages/jam/transition/externalities/refine-fetch-externalities.test.d.ts.map +1 -0
- package/packages/jam/transition/externalities/refine-fetch-externalities.test.js +32 -0
- package/packages/jam/transition/externalities/fetch-externalities.test.d.ts +0 -2
- package/packages/jam/transition/externalities/fetch-externalities.test.d.ts.map +0 -1
- 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
|
|
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
|
|
37
|
-
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
99
|
-
const fetchMock = new
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
207
|
+
const fetchMock = new RefineFetchMock();
|
|
204
208
|
fetchMock.authorizerResponse = blob;
|
|
205
|
-
const { registers, memory, readBack, expectedLength } = prepareRegsAndMemory(blob, FetchKind.
|
|
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
|
|
219
|
+
const fetchMock = new RefineFetchMock();
|
|
216
220
|
fetchMock.authorizationTokenResponse = blob;
|
|
217
|
-
const { registers, memory, readBack, expectedLength } = prepareRegsAndMemory(blob, FetchKind.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
282
|
-
fetchMock.
|
|
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
|
|
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
|
|
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 =
|
|
379
|
+
authorizerTraceResponse = BytesBlob.empty();
|
|
341
380
|
workItemExtrinsicResponses = new Map();
|
|
342
381
|
workItemImportResponses = new Map();
|
|
343
|
-
workPackageResponse =
|
|
344
|
-
authorizerResponse =
|
|
345
|
-
authorizationTokenResponse =
|
|
346
|
-
refineContextResponse =
|
|
347
|
-
allWorkItemsResponse =
|
|
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
|
-
|
|
423
|
+
authConfiguration() {
|
|
388
424
|
return this.authorizerResponse;
|
|
389
425
|
}
|
|
390
|
-
|
|
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
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
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.
|
|
425
|
-
}
|
|
426
|
-
allTransfers() {
|
|
427
|
-
return this.allTransfersResponse;
|
|
463
|
+
return this.constantsResponse;
|
|
428
464
|
}
|
|
429
|
-
|
|
430
|
-
this.
|
|
431
|
-
|
|
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.
|
|
469
|
+
return this.entropyResponse;
|
|
436
470
|
}
|
|
437
471
|
allTransfersAndOperands() {
|
|
438
|
-
return this.
|
|
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
|
-
|
|
33
|
-
|
|
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 {
|
|
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 =
|
|
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
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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
|
|
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>,
|
|
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":"AAAA,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,QAAQ,EAId,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,KAAK,EAAE,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,KAAK,
|
|
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,
|
|
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
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
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) {
|