@typeberry/lib 0.5.11-10b197e → 0.5.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/packages/jam/in-core/externalities/index.d.ts +4 -0
- package/packages/jam/in-core/externalities/index.d.ts.map +1 -0
- package/packages/jam/in-core/externalities/index.js +3 -0
- package/packages/jam/{transition/externalities/is-authorized-fetch-externalities.d.ts → in-core/externalities/is-authorized-fetch.d.ts} +7 -9
- package/packages/jam/in-core/externalities/is-authorized-fetch.d.ts.map +1 -0
- package/packages/jam/in-core/externalities/is-authorized-fetch.js +41 -0
- package/packages/jam/in-core/externalities/is-authorized-fetch.test.d.ts +2 -0
- package/packages/jam/in-core/externalities/is-authorized-fetch.test.d.ts.map +1 -0
- package/packages/jam/in-core/externalities/is-authorized-fetch.test.js +101 -0
- package/packages/jam/in-core/externalities/refine-fetch.d.ts +51 -0
- package/packages/jam/in-core/externalities/refine-fetch.d.ts.map +1 -0
- package/packages/jam/in-core/externalities/refine-fetch.js +80 -0
- package/packages/jam/in-core/externalities/refine-fetch.test.d.ts +2 -0
- package/packages/jam/in-core/externalities/refine-fetch.test.d.ts.map +1 -0
- package/packages/jam/in-core/externalities/refine-fetch.test.js +219 -0
- package/packages/jam/in-core/in-core.d.ts +2 -2
- package/packages/jam/in-core/in-core.d.ts.map +1 -1
- package/packages/jam/in-core/in-core.js +6 -4
- package/packages/jam/in-core/is-authorized.d.ts +3 -2
- package/packages/jam/in-core/is-authorized.d.ts.map +1 -1
- package/packages/jam/in-core/is-authorized.js +7 -6
- package/packages/jam/in-core/is-authorized.test.js +49 -7
- package/packages/jam/in-core/refine.d.ts +5 -8
- package/packages/jam/in-core/refine.d.ts.map +1 -1
- package/packages/jam/in-core/refine.js +12 -6
- package/packages/jam/transition/externalities/fetch-externalities.d.ts +55 -2
- package/packages/jam/transition/externalities/fetch-externalities.d.ts.map +1 -1
- package/packages/jam/transition/externalities/fetch-externalities.js +44 -2
- package/packages/jam/transition/externalities/index.d.ts +0 -2
- package/packages/jam/transition/externalities/index.d.ts.map +1 -1
- package/packages/jam/transition/externalities/index.js +0 -2
- package/packages/jam/transition/externalities/is-authorized-fetch-externalities.d.ts.map +0 -1
- package/packages/jam/transition/externalities/is-authorized-fetch-externalities.js +0 -41
- package/packages/jam/transition/externalities/refine-fetch-externalities.d.ts +0 -24
- package/packages/jam/transition/externalities/refine-fetch-externalities.d.ts.map +0 -1
- package/packages/jam/transition/externalities/refine-fetch-externalities.js +0 -59
- package/packages/jam/transition/externalities/refine-fetch-externalities.test.d.ts +0 -2
- package/packages/jam/transition/externalities/refine-fetch-externalities.test.d.ts.map +0 -1
- package/packages/jam/transition/externalities/refine-fetch-externalities.test.js +0 -32
package/package.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../packages/jam/in-core/externalities/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC"}
|
|
@@ -1,22 +1,20 @@
|
|
|
1
|
-
import { BytesBlob } from "#@typeberry/bytes";
|
|
1
|
+
import type { BytesBlob } from "#@typeberry/bytes";
|
|
2
2
|
import type { ChainSpec } from "#@typeberry/config";
|
|
3
3
|
import { general } from "#@typeberry/jam-host-calls";
|
|
4
4
|
import type { U64 } from "#@typeberry/numbers";
|
|
5
|
+
import { type WorkPackageFetchData } from "#@typeberry/transition/externalities/fetch-externalities.js";
|
|
5
6
|
export declare class IsAuthorizedFetchExternalities implements general.IIsAuthorizedFetch {
|
|
6
7
|
private readonly chainSpec;
|
|
7
|
-
private readonly
|
|
8
|
+
private readonly pkg;
|
|
8
9
|
readonly context = general.FetchContext.IsAuthorized;
|
|
9
|
-
constructor(chainSpec: ChainSpec,
|
|
10
|
-
authToken: BytesBlob;
|
|
11
|
-
authConfiguration: BytesBlob;
|
|
12
|
-
});
|
|
10
|
+
constructor(chainSpec: ChainSpec, pkg: WorkPackageFetchData);
|
|
13
11
|
constants(): BytesBlob;
|
|
14
12
|
workPackage(): BytesBlob;
|
|
15
13
|
authConfiguration(): BytesBlob;
|
|
16
14
|
authToken(): BytesBlob;
|
|
17
15
|
refineContext(): BytesBlob;
|
|
18
16
|
allWorkItems(): BytesBlob;
|
|
19
|
-
oneWorkItem(
|
|
20
|
-
workItemPayload(
|
|
17
|
+
oneWorkItem(workItem: U64): BytesBlob | null;
|
|
18
|
+
workItemPayload(workItem: U64): BytesBlob | null;
|
|
21
19
|
}
|
|
22
|
-
//# sourceMappingURL=is-authorized-fetch
|
|
20
|
+
//# sourceMappingURL=is-authorized-fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-authorized-fetch.d.ts","sourceRoot":"","sources":["../../../../../../packages/jam/in-core/externalities/is-authorized-fetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACpD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,4DAA4D,CAAC;AAEpE,qBAAa,8BAA+B,YAAW,OAAO,CAAC,kBAAkB;IAI7E,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,GAAG;IAJtB,QAAQ,CAAC,OAAO,qCAAqC;gBAGlC,SAAS,EAAE,SAAS,EACpB,GAAG,EAAE,oBAAoB;IAG5C,SAAS,IAAI,SAAS;IAItB,WAAW,IAAI,SAAS;IAIxB,iBAAiB,IAAI,SAAS;IAI9B,SAAS,IAAI,SAAS;IAItB,aAAa,IAAI,SAAS;IAI1B,YAAY,IAAI,SAAS;IAIzB,WAAW,CAAC,QAAQ,EAAE,GAAG,GAAG,SAAS,GAAG,IAAI;IAK5C,eAAe,CAAC,QAAQ,EAAE,GAAG,GAAG,SAAS,GAAG,IAAI;CAQjD"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { general } from "#@typeberry/jam-host-calls";
|
|
2
|
+
import { getEncodedConstants, u64ToArrayIndex, } from "#@typeberry/transition/externalities/fetch-externalities.js";
|
|
3
|
+
export class IsAuthorizedFetchExternalities {
|
|
4
|
+
chainSpec;
|
|
5
|
+
pkg;
|
|
6
|
+
context = general.FetchContext.IsAuthorized;
|
|
7
|
+
constructor(chainSpec, pkg) {
|
|
8
|
+
this.chainSpec = chainSpec;
|
|
9
|
+
this.pkg = pkg;
|
|
10
|
+
}
|
|
11
|
+
constants() {
|
|
12
|
+
return getEncodedConstants(this.chainSpec);
|
|
13
|
+
}
|
|
14
|
+
workPackage() {
|
|
15
|
+
return this.pkg.packageView.encoded();
|
|
16
|
+
}
|
|
17
|
+
authConfiguration() {
|
|
18
|
+
return this.pkg.packageView.authConfiguration.view();
|
|
19
|
+
}
|
|
20
|
+
authToken() {
|
|
21
|
+
return this.pkg.packageView.authToken.view();
|
|
22
|
+
}
|
|
23
|
+
refineContext() {
|
|
24
|
+
return this.pkg.packageView.context.encoded();
|
|
25
|
+
}
|
|
26
|
+
allWorkItems() {
|
|
27
|
+
return this.pkg.workItemSummaries.encoded();
|
|
28
|
+
}
|
|
29
|
+
oneWorkItem(workItem) {
|
|
30
|
+
const idx = u64ToArrayIndex(workItem, this.pkg.workItemSummaries.length);
|
|
31
|
+
return idx === null ? null : (this.pkg.workItemSummaries.get(idx)?.encoded() ?? null);
|
|
32
|
+
}
|
|
33
|
+
workItemPayload(workItem) {
|
|
34
|
+
const items = this.pkg.packageView.items.view();
|
|
35
|
+
const idx = u64ToArrayIndex(workItem, items.length);
|
|
36
|
+
if (idx === null) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
return items.get(idx)?.view().payload.view() ?? null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-authorized-fetch.test.d.ts","sourceRoot":"","sources":["../../../../../../packages/jam/in-core/externalities/is-authorized-fetch.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import assert from "node:assert";
|
|
2
|
+
import { describe, it } from "node:test";
|
|
3
|
+
import { tryAsServiceGas, tryAsServiceId, tryAsTimeSlot } from "#@typeberry/block";
|
|
4
|
+
import { RefineContext } from "#@typeberry/block/refine-context.js";
|
|
5
|
+
import { WorkItem } from "#@typeberry/block/work-item.js";
|
|
6
|
+
import { tryAsWorkItemsCount, WorkPackage } from "#@typeberry/block/work-package.js";
|
|
7
|
+
import { Bytes, BytesBlob } from "#@typeberry/bytes";
|
|
8
|
+
import { Encoder } from "#@typeberry/codec";
|
|
9
|
+
import { asKnownSize, FixedSizeArray } from "#@typeberry/collections";
|
|
10
|
+
import { fullChainSpec, tinyChainSpec } from "#@typeberry/config";
|
|
11
|
+
import { HASH_SIZE } from "#@typeberry/hash";
|
|
12
|
+
import { tryAsU16, tryAsU64 } from "#@typeberry/numbers";
|
|
13
|
+
import { buildWorkPackageFetchData } from "#@typeberry/transition/externalities/fetch-externalities.js";
|
|
14
|
+
import { IsAuthorizedFetchExternalities } from "./is-authorized-fetch.js";
|
|
15
|
+
function fetchDataFor(pkg, chainSpec = tinyChainSpec) {
|
|
16
|
+
return buildWorkPackageFetchData(chainSpec, pkg);
|
|
17
|
+
}
|
|
18
|
+
function buildWorkItem(overrides = {}) {
|
|
19
|
+
return WorkItem.create({
|
|
20
|
+
service: tryAsServiceId(overrides.service ?? 1),
|
|
21
|
+
codeHash: Bytes.fill(HASH_SIZE, 7).asOpaque(),
|
|
22
|
+
payload: BytesBlob.blobFrom(new Uint8Array(overrides.payloadLen ?? 3).fill(0xab)),
|
|
23
|
+
refineGasLimit: tryAsServiceGas(1_000_000),
|
|
24
|
+
accumulateGasLimit: tryAsServiceGas(2_000_000),
|
|
25
|
+
importSegments: asKnownSize([]),
|
|
26
|
+
extrinsic: [],
|
|
27
|
+
exportCount: tryAsU16(0),
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
function buildPackage(items = [buildWorkItem({})]) {
|
|
31
|
+
return WorkPackage.create({
|
|
32
|
+
authToken: BytesBlob.blobFrom(new Uint8Array([1, 2, 3])),
|
|
33
|
+
authCodeHost: tryAsServiceId(42),
|
|
34
|
+
authCodeHash: Bytes.fill(HASH_SIZE, 9).asOpaque(),
|
|
35
|
+
authConfiguration: BytesBlob.blobFrom(new Uint8Array([4, 5, 6, 7])),
|
|
36
|
+
context: RefineContext.create({
|
|
37
|
+
anchor: Bytes.fill(HASH_SIZE, 1).asOpaque(),
|
|
38
|
+
stateRoot: Bytes.fill(HASH_SIZE, 2).asOpaque(),
|
|
39
|
+
beefyRoot: Bytes.fill(HASH_SIZE, 3).asOpaque(),
|
|
40
|
+
lookupAnchor: Bytes.fill(HASH_SIZE, 4).asOpaque(),
|
|
41
|
+
lookupAnchorSlot: tryAsTimeSlot(16),
|
|
42
|
+
prerequisites: [],
|
|
43
|
+
}),
|
|
44
|
+
items: FixedSizeArray.new(items, tryAsWorkItemsCount(items.length)),
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
describe("IsAuthorizedFetchExternalities", () => {
|
|
48
|
+
it("returns different constants for different chain specs", () => {
|
|
49
|
+
const tinyExt = new IsAuthorizedFetchExternalities(tinyChainSpec, fetchDataFor(buildPackage(), tinyChainSpec));
|
|
50
|
+
const fullExt = new IsAuthorizedFetchExternalities(fullChainSpec, fetchDataFor(buildPackage(), fullChainSpec));
|
|
51
|
+
assert.notStrictEqual(tinyExt.constants().length, 0);
|
|
52
|
+
assert.notDeepStrictEqual(tinyExt.constants(), fullExt.constants());
|
|
53
|
+
});
|
|
54
|
+
it("returns encoded work package", () => {
|
|
55
|
+
const pkg = buildPackage();
|
|
56
|
+
const ext = new IsAuthorizedFetchExternalities(tinyChainSpec, fetchDataFor(pkg));
|
|
57
|
+
const expected = Encoder.encodeObject(WorkPackage.Codec, pkg, tinyChainSpec);
|
|
58
|
+
assert.deepStrictEqual(ext.workPackage().raw, expected.raw);
|
|
59
|
+
});
|
|
60
|
+
it("returns auth configuration and auth token from the package", () => {
|
|
61
|
+
const ext = new IsAuthorizedFetchExternalities(tinyChainSpec, fetchDataFor(buildPackage()));
|
|
62
|
+
assert.deepStrictEqual(ext.authConfiguration().raw, new Uint8Array([4, 5, 6, 7]));
|
|
63
|
+
assert.deepStrictEqual(ext.authToken().raw, new Uint8Array([1, 2, 3]));
|
|
64
|
+
});
|
|
65
|
+
it("returns encoded refine context", () => {
|
|
66
|
+
const pkg = buildPackage();
|
|
67
|
+
const ext = new IsAuthorizedFetchExternalities(tinyChainSpec, fetchDataFor(pkg));
|
|
68
|
+
const expected = Encoder.encodeObject(RefineContext.Codec, pkg.context);
|
|
69
|
+
assert.deepStrictEqual(ext.refineContext().raw, expected.raw);
|
|
70
|
+
});
|
|
71
|
+
it("returns concatenated work item summaries with 62 bytes per item", () => {
|
|
72
|
+
const items = [buildWorkItem({ service: 1 }), buildWorkItem({ service: 2, payloadLen: 5 })];
|
|
73
|
+
const ext = new IsAuthorizedFetchExternalities(tinyChainSpec, fetchDataFor(buildPackage(items)));
|
|
74
|
+
assert.strictEqual(ext.allWorkItems().length, 62 * items.length);
|
|
75
|
+
});
|
|
76
|
+
it("returns a single work item summary (kind 12)", () => {
|
|
77
|
+
const items = [buildWorkItem({ service: 1 }), buildWorkItem({ service: 2, payloadLen: 10 })];
|
|
78
|
+
const ext = new IsAuthorizedFetchExternalities(tinyChainSpec, fetchDataFor(buildPackage(items)));
|
|
79
|
+
const one = ext.oneWorkItem(tryAsU64(1));
|
|
80
|
+
assert.ok(one !== null);
|
|
81
|
+
assert.strictEqual(one.length, 62);
|
|
82
|
+
const serviceId = new DataView(one.raw.buffer, one.raw.byteOffset, 4).getUint32(0, true);
|
|
83
|
+
assert.strictEqual(serviceId, 2);
|
|
84
|
+
});
|
|
85
|
+
it("returns null for one work item when index is out of range", () => {
|
|
86
|
+
const ext = new IsAuthorizedFetchExternalities(tinyChainSpec, fetchDataFor(buildPackage()));
|
|
87
|
+
assert.strictEqual(ext.oneWorkItem(tryAsU64(99)), null);
|
|
88
|
+
});
|
|
89
|
+
it("returns the raw payload of a work item (kind 13)", () => {
|
|
90
|
+
const items = [buildWorkItem({ service: 1, payloadLen: 2 }), buildWorkItem({ service: 2, payloadLen: 5 })];
|
|
91
|
+
const ext = new IsAuthorizedFetchExternalities(tinyChainSpec, fetchDataFor(buildPackage(items)));
|
|
92
|
+
const payload = ext.workItemPayload(tryAsU64(1));
|
|
93
|
+
assert.ok(payload !== null);
|
|
94
|
+
assert.strictEqual(payload.length, 5);
|
|
95
|
+
assert.ok(payload.raw.every((x) => x === 0xab));
|
|
96
|
+
});
|
|
97
|
+
it("returns null for payload when index is out of range", () => {
|
|
98
|
+
const ext = new IsAuthorizedFetchExternalities(tinyChainSpec, fetchDataFor(buildPackage()));
|
|
99
|
+
assert.strictEqual(ext.workItemPayload(tryAsU64(99)), null);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { EntropyHash, Segment, SegmentIndex } from "#@typeberry/block";
|
|
2
|
+
import type { WorkItemExtrinsic } from "#@typeberry/block/work-item.js";
|
|
3
|
+
import { type BytesBlob } from "#@typeberry/bytes";
|
|
4
|
+
import type { KnownSizeArray } from "#@typeberry/collections";
|
|
5
|
+
import type { ChainSpec } from "#@typeberry/config";
|
|
6
|
+
import { general } from "#@typeberry/jam-host-calls";
|
|
7
|
+
import type { U64 } from "#@typeberry/numbers";
|
|
8
|
+
import { type WorkPackageFetchData } from "#@typeberry/transition/externalities/fetch-externalities.js";
|
|
9
|
+
/** A single decoded import segment passed into refine. */
|
|
10
|
+
export type ImportedSegment = {
|
|
11
|
+
index: SegmentIndex;
|
|
12
|
+
data: Segment;
|
|
13
|
+
};
|
|
14
|
+
/** An array whose length matches the work-package's work-item count. */
|
|
15
|
+
export type PerWorkItem<T> = KnownSizeArray<T, "for each work item">;
|
|
16
|
+
export type RefineFetchData = {
|
|
17
|
+
/** Pre-computed per-work-package encodings. */
|
|
18
|
+
packageData: WorkPackageFetchData;
|
|
19
|
+
/** Index of the work item currently being refined (`i` in GP). */
|
|
20
|
+
currentWorkItemIndex: number;
|
|
21
|
+
/** Imports per work item (`ī`). */
|
|
22
|
+
imports: PerWorkItem<ImportedSegment[]>;
|
|
23
|
+
/** Extrinsics per work item (`x̄`). */
|
|
24
|
+
extrinsics: PerWorkItem<WorkItemExtrinsic[]>;
|
|
25
|
+
/** Authorizer trace produced by Is-Authorized (`r`). */
|
|
26
|
+
authorizerTrace: BytesBlob;
|
|
27
|
+
};
|
|
28
|
+
export declare class RefineFetchExternalities implements general.IRefineFetch {
|
|
29
|
+
private readonly chainSpec;
|
|
30
|
+
private readonly data;
|
|
31
|
+
readonly context = general.FetchContext.Refine;
|
|
32
|
+
constructor(chainSpec: ChainSpec, data: RefineFetchData);
|
|
33
|
+
constants(): BytesBlob;
|
|
34
|
+
/**
|
|
35
|
+
* Refine entropy is `H₀` (zero hash) per GP §B.3.
|
|
36
|
+
*
|
|
37
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/2fe0012fe201?v=0.7.2
|
|
38
|
+
*/
|
|
39
|
+
entropy(): EntropyHash;
|
|
40
|
+
authorizerTrace(): BytesBlob;
|
|
41
|
+
workItemExtrinsic(workItem: U64 | null, index: U64): BytesBlob | null;
|
|
42
|
+
workItemImport(workItem: U64 | null, index: U64): BytesBlob | null;
|
|
43
|
+
workPackage(): BytesBlob;
|
|
44
|
+
authConfiguration(): BytesBlob;
|
|
45
|
+
authToken(): BytesBlob;
|
|
46
|
+
refineContext(): BytesBlob;
|
|
47
|
+
allWorkItems(): BytesBlob;
|
|
48
|
+
oneWorkItem(workItem: U64): BytesBlob | null;
|
|
49
|
+
workItemPayload(workItem: U64): BytesBlob | null;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=refine-fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refine-fetch.d.ts","sourceRoot":"","sources":["../../../../../../packages/jam/in-core/externalities/refine-fetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAS,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACpD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,4DAA4D,CAAC;AAEpE,0DAA0D;AAC1D,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,YAAY,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AAEF,wEAAwE;AACxE,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,cAAc,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC;AAErE,MAAM,MAAM,eAAe,GAAG;IAC5B,+CAA+C;IAC/C,WAAW,EAAE,oBAAoB,CAAC;IAClC,kEAAkE;IAClE,oBAAoB,EAAE,MAAM,CAAC;IAC7B,mCAAmC;IACnC,OAAO,EAAE,WAAW,CAAC,eAAe,EAAE,CAAC,CAAC;IACxC,uCAAuC;IACvC,UAAU,EAAE,WAAW,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAC7C,wDAAwD;IACxD,eAAe,EAAE,SAAS,CAAC;CAC5B,CAAC;AAEF,qBAAa,wBAAyB,YAAW,OAAO,CAAC,YAAY;IAIjE,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,IAAI;IAJvB,QAAQ,CAAC,OAAO,+BAA+B;gBAG5B,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,eAAe;IAGxC,SAAS,IAAI,SAAS;IAItB;;;;OAIG;IACH,OAAO,IAAI,WAAW;IAItB,eAAe,IAAI,SAAS;IAI5B,iBAAiB,CAAC,QAAQ,EAAE,GAAG,GAAG,IAAI,EAAE,KAAK,EAAE,GAAG,GAAG,SAAS,GAAG,IAAI;IAcrE,cAAc,CAAC,QAAQ,EAAE,GAAG,GAAG,IAAI,EAAE,KAAK,EAAE,GAAG,GAAG,SAAS,GAAG,IAAI;IAelE,WAAW,IAAI,SAAS;IAIxB,iBAAiB,IAAI,SAAS;IAI9B,SAAS,IAAI,SAAS;IAItB,aAAa,IAAI,SAAS;IAI1B,YAAY,IAAI,SAAS;IAIzB,WAAW,CAAC,QAAQ,EAAE,GAAG,GAAG,SAAS,GAAG,IAAI;IAM5C,eAAe,CAAC,QAAQ,EAAE,GAAG,GAAG,SAAS,GAAG,IAAI;CAQjD"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Bytes } from "#@typeberry/bytes";
|
|
2
|
+
import { HASH_SIZE } from "#@typeberry/hash";
|
|
3
|
+
import { general } from "#@typeberry/jam-host-calls";
|
|
4
|
+
import { getEncodedConstants, u64ToArrayIndex, } from "#@typeberry/transition/externalities/fetch-externalities.js";
|
|
5
|
+
export class RefineFetchExternalities {
|
|
6
|
+
chainSpec;
|
|
7
|
+
data;
|
|
8
|
+
context = general.FetchContext.Refine;
|
|
9
|
+
constructor(chainSpec, data) {
|
|
10
|
+
this.chainSpec = chainSpec;
|
|
11
|
+
this.data = data;
|
|
12
|
+
}
|
|
13
|
+
constants() {
|
|
14
|
+
return getEncodedConstants(this.chainSpec);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Refine entropy is `H₀` (zero hash) per GP §B.3.
|
|
18
|
+
*
|
|
19
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/2fe0012fe201?v=0.7.2
|
|
20
|
+
*/
|
|
21
|
+
entropy() {
|
|
22
|
+
return Bytes.zero(HASH_SIZE).asOpaque();
|
|
23
|
+
}
|
|
24
|
+
authorizerTrace() {
|
|
25
|
+
return this.data.authorizerTrace;
|
|
26
|
+
}
|
|
27
|
+
workItemExtrinsic(workItem, index) {
|
|
28
|
+
const itemIdx = workItem === null ? this.data.currentWorkItemIndex : u64ToArrayIndex(workItem, this.data.extrinsics.length);
|
|
29
|
+
if (itemIdx === null) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const perItem = this.data.extrinsics[itemIdx];
|
|
33
|
+
const xIdx = u64ToArrayIndex(index, perItem.length);
|
|
34
|
+
if (xIdx === null) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
return perItem[xIdx];
|
|
38
|
+
}
|
|
39
|
+
workItemImport(workItem, index) {
|
|
40
|
+
const itemIdx = workItem === null ? this.data.currentWorkItemIndex : u64ToArrayIndex(workItem, this.data.imports.length);
|
|
41
|
+
if (itemIdx === null) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
const perItem = this.data.imports[itemIdx];
|
|
45
|
+
const segIdx = u64ToArrayIndex(index, perItem.length);
|
|
46
|
+
if (segIdx === null) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
// `Segment` extends `BytesBlob`, so it can be returned directly.
|
|
50
|
+
return perItem[segIdx].data;
|
|
51
|
+
}
|
|
52
|
+
workPackage() {
|
|
53
|
+
return this.data.packageData.packageView.encoded();
|
|
54
|
+
}
|
|
55
|
+
authConfiguration() {
|
|
56
|
+
return this.data.packageData.packageView.authConfiguration.view();
|
|
57
|
+
}
|
|
58
|
+
authToken() {
|
|
59
|
+
return this.data.packageData.packageView.authToken.view();
|
|
60
|
+
}
|
|
61
|
+
refineContext() {
|
|
62
|
+
return this.data.packageData.packageView.context.encoded();
|
|
63
|
+
}
|
|
64
|
+
allWorkItems() {
|
|
65
|
+
return this.data.packageData.workItemSummaries.encoded();
|
|
66
|
+
}
|
|
67
|
+
oneWorkItem(workItem) {
|
|
68
|
+
const summaries = this.data.packageData.workItemSummaries;
|
|
69
|
+
const idx = u64ToArrayIndex(workItem, summaries.length);
|
|
70
|
+
return idx === null ? null : (summaries.get(idx)?.encoded() ?? null);
|
|
71
|
+
}
|
|
72
|
+
workItemPayload(workItem) {
|
|
73
|
+
const items = this.data.packageData.packageView.items.view();
|
|
74
|
+
const idx = u64ToArrayIndex(workItem, items.length);
|
|
75
|
+
if (idx === null) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
return items.get(idx)?.view().payload.view() ?? null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refine-fetch.test.d.ts","sourceRoot":"","sources":["../../../../../../packages/jam/in-core/externalities/refine-fetch.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import assert from "node:assert";
|
|
2
|
+
import { describe, it } from "node:test";
|
|
3
|
+
import { tryAsServiceGas, tryAsServiceId, tryAsTimeSlot } from "#@typeberry/block";
|
|
4
|
+
import { RefineContext } from "#@typeberry/block/refine-context.js";
|
|
5
|
+
import { ImportSpec, WorkItem, WorkItemExtrinsicSpec } from "#@typeberry/block/work-item.js";
|
|
6
|
+
import { SEGMENT_BYTES, tryAsSegmentIndex } from "#@typeberry/block/work-item-segment.js";
|
|
7
|
+
import { tryAsWorkItemsCount, WorkPackage } from "#@typeberry/block/work-package.js";
|
|
8
|
+
import { Bytes, BytesBlob } from "#@typeberry/bytes";
|
|
9
|
+
import { Encoder } from "#@typeberry/codec";
|
|
10
|
+
import { asKnownSize, FixedSizeArray } from "#@typeberry/collections";
|
|
11
|
+
import { fullChainSpec, tinyChainSpec } from "#@typeberry/config";
|
|
12
|
+
import { HASH_SIZE } from "#@typeberry/hash";
|
|
13
|
+
import { tryAsU16, tryAsU32, tryAsU64 } from "#@typeberry/numbers";
|
|
14
|
+
import { buildWorkPackageFetchData } from "#@typeberry/transition/externalities/fetch-externalities.js";
|
|
15
|
+
import { asOpaqueType } from "#@typeberry/utils";
|
|
16
|
+
import { RefineFetchExternalities } from "./refine-fetch.js";
|
|
17
|
+
const asExtrinsic = (bytes) => asOpaqueType(bytes);
|
|
18
|
+
function buildWorkItem(overrides) {
|
|
19
|
+
const codeHash = Bytes.fill(HASH_SIZE, 7).asOpaque();
|
|
20
|
+
const imports = Array.from({ length: overrides.importCount ?? 0 }, (_, i) => ImportSpec.create({ treeRoot: Bytes.zero(HASH_SIZE), index: tryAsSegmentIndex(i) }));
|
|
21
|
+
const extrinsicSpecs = Array.from({ length: overrides.extrinsicCount ?? 0 }, () => WorkItemExtrinsicSpec.create({ hash: Bytes.zero(HASH_SIZE).asOpaque(), len: tryAsU32(0) }));
|
|
22
|
+
return WorkItem.create({
|
|
23
|
+
service: tryAsServiceId(overrides.service ?? 1),
|
|
24
|
+
codeHash,
|
|
25
|
+
payload: BytesBlob.blobFrom(new Uint8Array(overrides.payloadLen ?? 3).fill(0xab)),
|
|
26
|
+
refineGasLimit: tryAsServiceGas(1_000_000),
|
|
27
|
+
accumulateGasLimit: tryAsServiceGas(2_000_000),
|
|
28
|
+
importSegments: asKnownSize(imports),
|
|
29
|
+
extrinsic: extrinsicSpecs,
|
|
30
|
+
exportCount: tryAsU16(overrides.exportCount ?? 0),
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function buildWorkPackage(items) {
|
|
34
|
+
return WorkPackage.create({
|
|
35
|
+
authToken: BytesBlob.blobFrom(new Uint8Array([1, 2, 3])),
|
|
36
|
+
authCodeHost: tryAsServiceId(42),
|
|
37
|
+
authCodeHash: Bytes.fill(HASH_SIZE, 9).asOpaque(),
|
|
38
|
+
authConfiguration: BytesBlob.blobFrom(new Uint8Array([4, 5, 6, 7])),
|
|
39
|
+
context: RefineContext.create({
|
|
40
|
+
anchor: Bytes.fill(HASH_SIZE, 1).asOpaque(),
|
|
41
|
+
stateRoot: Bytes.fill(HASH_SIZE, 2).asOpaque(),
|
|
42
|
+
beefyRoot: Bytes.fill(HASH_SIZE, 3).asOpaque(),
|
|
43
|
+
lookupAnchor: Bytes.fill(HASH_SIZE, 4).asOpaque(),
|
|
44
|
+
lookupAnchorSlot: tryAsTimeSlot(16),
|
|
45
|
+
prerequisites: [],
|
|
46
|
+
}),
|
|
47
|
+
items: FixedSizeArray.new(items, tryAsWorkItemsCount(items.length)),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
function prepareRefineData(opts = {}) {
|
|
51
|
+
const chainSpec = opts.chainSpec ?? tinyChainSpec;
|
|
52
|
+
const items = opts.items ?? [buildWorkItem({})];
|
|
53
|
+
const workPackage = buildWorkPackage(items);
|
|
54
|
+
const packageData = buildWorkPackageFetchData(chainSpec, workPackage);
|
|
55
|
+
return new RefineFetchExternalities(chainSpec, {
|
|
56
|
+
packageData,
|
|
57
|
+
currentWorkItemIndex: opts.currentWorkItemIndex ?? 0,
|
|
58
|
+
imports: opts.imports ?? asKnownSize(items.map(() => [])),
|
|
59
|
+
extrinsics: opts.extrinsics ?? asKnownSize(items.map(() => [])),
|
|
60
|
+
authorizerTrace: opts.authorizerTrace ?? BytesBlob.empty(),
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
describe("RefineFetchExternalities", () => {
|
|
64
|
+
it("should return different constants for different chain specs", () => {
|
|
65
|
+
const tinyExt = prepareRefineData({ chainSpec: tinyChainSpec });
|
|
66
|
+
const fullExt = prepareRefineData({ chainSpec: fullChainSpec });
|
|
67
|
+
assert.notStrictEqual(tinyExt.constants().length, 0);
|
|
68
|
+
assert.notStrictEqual(fullExt.constants().length, 0);
|
|
69
|
+
assert.notDeepStrictEqual(tinyExt.constants(), fullExt.constants());
|
|
70
|
+
});
|
|
71
|
+
it("should return entropy H_0 (zero hash) per GP §B.3", () => {
|
|
72
|
+
const ext = prepareRefineData();
|
|
73
|
+
const entropy = ext.entropy();
|
|
74
|
+
assert.strictEqual(entropy.length, HASH_SIZE);
|
|
75
|
+
assert.ok(entropy.isEqualTo(Bytes.zero(HASH_SIZE).asOpaque()));
|
|
76
|
+
});
|
|
77
|
+
it("should return the supplied authorizer trace", () => {
|
|
78
|
+
const trace = BytesBlob.blobFrom(new Uint8Array([0xaa, 0xbb, 0xcc]));
|
|
79
|
+
const ext = prepareRefineData({ authorizerTrace: trace });
|
|
80
|
+
assert.deepStrictEqual(ext.authorizerTrace().raw, trace.raw);
|
|
81
|
+
});
|
|
82
|
+
it("should return an extrinsic by work item index and extrinsic index", () => {
|
|
83
|
+
const items = [buildWorkItem({}), buildWorkItem({ service: 2 })];
|
|
84
|
+
const extrinsics = asKnownSize([
|
|
85
|
+
[asExtrinsic(BytesBlob.blobFrom(new Uint8Array([1])))],
|
|
86
|
+
[
|
|
87
|
+
asExtrinsic(BytesBlob.blobFrom(new Uint8Array([2, 2]))),
|
|
88
|
+
asExtrinsic(BytesBlob.blobFrom(new Uint8Array([3, 3, 3]))),
|
|
89
|
+
],
|
|
90
|
+
]);
|
|
91
|
+
const ext = prepareRefineData({ items, extrinsics });
|
|
92
|
+
const other = ext.workItemExtrinsic(tryAsU64(1), tryAsU64(1));
|
|
93
|
+
assert.ok(other !== null);
|
|
94
|
+
assert.deepStrictEqual(other.raw, new Uint8Array([3, 3, 3]));
|
|
95
|
+
});
|
|
96
|
+
it("should return current item's extrinsic when workItem is null", () => {
|
|
97
|
+
const items = [buildWorkItem({}), buildWorkItem({ service: 2 })];
|
|
98
|
+
const extrinsics = asKnownSize([
|
|
99
|
+
[asExtrinsic(BytesBlob.blobFrom(new Uint8Array([9])))],
|
|
100
|
+
[asExtrinsic(BytesBlob.blobFrom(new Uint8Array([8])))],
|
|
101
|
+
]);
|
|
102
|
+
const ext = prepareRefineData({ items, extrinsics, currentWorkItemIndex: 1 });
|
|
103
|
+
const mine = ext.workItemExtrinsic(null, tryAsU64(0));
|
|
104
|
+
assert.ok(mine !== null);
|
|
105
|
+
assert.deepStrictEqual(mine.raw, new Uint8Array([8]));
|
|
106
|
+
});
|
|
107
|
+
it("should return null for out-of-range extrinsic indices", () => {
|
|
108
|
+
const items = [buildWorkItem({})];
|
|
109
|
+
const extrinsics = asKnownSize([
|
|
110
|
+
[asExtrinsic(BytesBlob.blobFrom(new Uint8Array([1])))],
|
|
111
|
+
]);
|
|
112
|
+
const ext = prepareRefineData({ items, extrinsics });
|
|
113
|
+
assert.strictEqual(ext.workItemExtrinsic(tryAsU64(5), tryAsU64(0)), null);
|
|
114
|
+
assert.strictEqual(ext.workItemExtrinsic(tryAsU64(0), tryAsU64(5)), null);
|
|
115
|
+
assert.strictEqual(ext.workItemExtrinsic(null, tryAsU64(5)), null);
|
|
116
|
+
});
|
|
117
|
+
it("should treat U64 indices above the safe-integer range as out of range", () => {
|
|
118
|
+
const items = [buildWorkItem({})];
|
|
119
|
+
const ext = prepareRefineData({ items });
|
|
120
|
+
const huge = tryAsU64(2n ** 53n); // first value > Number.MAX_SAFE_INTEGER
|
|
121
|
+
assert.strictEqual(ext.workItemExtrinsic(huge, tryAsU64(0)), null);
|
|
122
|
+
assert.strictEqual(ext.workItemExtrinsic(null, huge), null);
|
|
123
|
+
assert.strictEqual(ext.workItemImport(huge, tryAsU64(0)), null);
|
|
124
|
+
assert.strictEqual(ext.oneWorkItem(huge), null);
|
|
125
|
+
assert.strictEqual(ext.workItemPayload(huge), null);
|
|
126
|
+
});
|
|
127
|
+
it("should return an import segment by work item index and segment index", () => {
|
|
128
|
+
const items = [buildWorkItem({}), buildWorkItem({ service: 2 })];
|
|
129
|
+
const segBytes = new Uint8Array(SEGMENT_BYTES).fill(0x55);
|
|
130
|
+
const imports = asKnownSize([
|
|
131
|
+
[],
|
|
132
|
+
[{ index: tryAsSegmentIndex(0), data: Bytes.fromBlob(segBytes, SEGMENT_BYTES) }],
|
|
133
|
+
]);
|
|
134
|
+
const ext = prepareRefineData({ items, imports });
|
|
135
|
+
const imp = ext.workItemImport(tryAsU64(1), tryAsU64(0));
|
|
136
|
+
assert.ok(imp !== null);
|
|
137
|
+
assert.deepStrictEqual(imp.raw, segBytes);
|
|
138
|
+
});
|
|
139
|
+
it("should return null for out-of-range import indices", () => {
|
|
140
|
+
const ext = prepareRefineData();
|
|
141
|
+
assert.strictEqual(ext.workItemImport(tryAsU64(10), tryAsU64(0)), null);
|
|
142
|
+
assert.strictEqual(ext.workItemImport(null, tryAsU64(10)), null);
|
|
143
|
+
assert.strictEqual(ext.workItemImport(tryAsU64(0), tryAsU64(10)), null);
|
|
144
|
+
});
|
|
145
|
+
it("should return encoded work package", () => {
|
|
146
|
+
const items = [buildWorkItem({})];
|
|
147
|
+
const ext = prepareRefineData({ items });
|
|
148
|
+
const expected = Encoder.encodeObject(WorkPackage.Codec, buildWorkPackage(items), tinyChainSpec);
|
|
149
|
+
assert.deepStrictEqual(ext.workPackage().raw, expected.raw);
|
|
150
|
+
});
|
|
151
|
+
it("should return auth configuration and auth token from the package", () => {
|
|
152
|
+
const ext = prepareRefineData();
|
|
153
|
+
assert.deepStrictEqual(ext.authConfiguration().raw, new Uint8Array([4, 5, 6, 7]));
|
|
154
|
+
assert.deepStrictEqual(ext.authToken().raw, new Uint8Array([1, 2, 3]));
|
|
155
|
+
});
|
|
156
|
+
it("should return encoded refine context", () => {
|
|
157
|
+
const ext = prepareRefineData();
|
|
158
|
+
const context = RefineContext.create({
|
|
159
|
+
anchor: Bytes.fill(HASH_SIZE, 1).asOpaque(),
|
|
160
|
+
stateRoot: Bytes.fill(HASH_SIZE, 2).asOpaque(),
|
|
161
|
+
beefyRoot: Bytes.fill(HASH_SIZE, 3).asOpaque(),
|
|
162
|
+
lookupAnchor: Bytes.fill(HASH_SIZE, 4).asOpaque(),
|
|
163
|
+
lookupAnchorSlot: tryAsTimeSlot(16),
|
|
164
|
+
prerequisites: [],
|
|
165
|
+
});
|
|
166
|
+
const expected = Encoder.encodeObject(RefineContext.Codec, context);
|
|
167
|
+
assert.deepStrictEqual(ext.refineContext().raw, expected.raw);
|
|
168
|
+
});
|
|
169
|
+
it("should return concatenated work item summaries (kind 11) with 62 bytes per item", () => {
|
|
170
|
+
const items = [
|
|
171
|
+
buildWorkItem({ service: 1, payloadLen: 7, exportCount: 2, importCount: 1, extrinsicCount: 0 }),
|
|
172
|
+
buildWorkItem({ service: 2, payloadLen: 4, exportCount: 0, importCount: 0, extrinsicCount: 3 }),
|
|
173
|
+
];
|
|
174
|
+
const ext = prepareRefineData({ items });
|
|
175
|
+
const all = ext.allWorkItems();
|
|
176
|
+
assert.strictEqual(all.length, 62 * items.length);
|
|
177
|
+
});
|
|
178
|
+
it("should return a single work item summary (kind 12)", () => {
|
|
179
|
+
const items = [buildWorkItem({ service: 1 }), buildWorkItem({ service: 2, payloadLen: 10 })];
|
|
180
|
+
const ext = prepareRefineData({ items });
|
|
181
|
+
const one = ext.oneWorkItem(tryAsU64(1));
|
|
182
|
+
assert.ok(one !== null);
|
|
183
|
+
assert.strictEqual(one.length, 62);
|
|
184
|
+
// first 4 bytes are the service id (u32 LE).
|
|
185
|
+
const serviceId = new DataView(one.raw.buffer, one.raw.byteOffset, 4).getUint32(0, true);
|
|
186
|
+
assert.strictEqual(serviceId, 2);
|
|
187
|
+
// payload length is the last 4 bytes (u32 LE).
|
|
188
|
+
const payloadLen = new DataView(one.raw.buffer, one.raw.byteOffset + 58, 4).getUint32(0, true);
|
|
189
|
+
assert.strictEqual(payloadLen, 10);
|
|
190
|
+
});
|
|
191
|
+
it("should return null for one work item when index is out of range", () => {
|
|
192
|
+
const ext = prepareRefineData();
|
|
193
|
+
assert.strictEqual(ext.oneWorkItem(tryAsU64(99)), null);
|
|
194
|
+
});
|
|
195
|
+
it("should return the raw payload of a work item (kind 13)", () => {
|
|
196
|
+
const items = [buildWorkItem({ service: 1, payloadLen: 2 }), buildWorkItem({ service: 2, payloadLen: 5 })];
|
|
197
|
+
const ext = prepareRefineData({ items });
|
|
198
|
+
const payload = ext.workItemPayload(tryAsU64(1));
|
|
199
|
+
assert.ok(payload !== null);
|
|
200
|
+
assert.strictEqual(payload.length, 5);
|
|
201
|
+
assert.ok(payload.raw.every((x) => x === 0xab));
|
|
202
|
+
});
|
|
203
|
+
it("should return null for payload when index is out of range", () => {
|
|
204
|
+
const ext = prepareRefineData();
|
|
205
|
+
assert.strictEqual(ext.workItemPayload(tryAsU64(99)), null);
|
|
206
|
+
});
|
|
207
|
+
// guard against silent accidental changes to the helpers — tryAsU32 ensures
|
|
208
|
+
// encoded lengths match GP's S(w) spec.
|
|
209
|
+
it("uses unsigned little-endian u32 for payload length regardless of platform", () => {
|
|
210
|
+
const items = [buildWorkItem({ service: 1, payloadLen: 0x1234 })];
|
|
211
|
+
const ext = prepareRefineData({ items });
|
|
212
|
+
const one = ext.oneWorkItem(tryAsU64(0));
|
|
213
|
+
assert.ok(one !== null);
|
|
214
|
+
const payloadLen = new DataView(one.raw.buffer, one.raw.byteOffset + 58, 4).getUint32(0, true);
|
|
215
|
+
assert.strictEqual(payloadLen, 0x1234);
|
|
216
|
+
// tryAsU32 would throw on negative values
|
|
217
|
+
assert.doesNotThrow(() => tryAsU32(0x1234));
|
|
218
|
+
});
|
|
219
|
+
});
|
|
@@ -7,8 +7,8 @@ import type { ChainSpec, PvmBackend } from "#@typeberry/config";
|
|
|
7
7
|
import type { StatesDb } from "#@typeberry/database";
|
|
8
8
|
import type { Blake2b, WithHash } from "#@typeberry/hash";
|
|
9
9
|
import { Result } from "#@typeberry/utils";
|
|
10
|
-
import {
|
|
11
|
-
export type { ImportedSegment, PerWorkItem
|
|
10
|
+
import type { ImportedSegment, PerWorkItem } from "./externalities/index.js";
|
|
11
|
+
export type { ImportedSegment, PerWorkItem };
|
|
12
12
|
export type RefineResult = {
|
|
13
13
|
report: WorkReport;
|
|
14
14
|
exports: PerWorkItem<Segment[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"in-core.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/in-core/in-core.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAsB,KAAK,eAAe,EAAmB,MAAM,oCAAoC,CAAC;AAC/G,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAmB,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAG9E,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"in-core.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/in-core/in-core.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAsB,KAAK,eAAe,EAAmB,MAAM,oCAAoC,CAAC;AAC/G,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAmB,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAG9E,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAKzD,OAAO,EAAe,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE7E,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,CAAC;AAI7C,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;CACjC,CAAC;AAEF,oBAAY,WAAW;IACrB,8EAA8E;IAC9E,YAAY,IAAI;IAChB,qFAAqF;IACrF,iBAAiB,IAAI;IACrB,wEAAwE;IACxE,uBAAuB,IAAI;IAC3B,2BAA2B;IAC3B,kBAAkB,IAAI;CACvB;AAID,qBAAa,MAAM;aASC,SAAS,EAAE,SAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM;IATzB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IAEpC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO;IAI3F,OAAO;IAUP;;;;;;;;;OASG;IACG,MAAM,CACV,kBAAkB,EAAE,QAAQ,CAAC,eAAe,EAAE,WAAW,CAAC,EAC1D,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,WAAW,CAAC,eAAe,EAAE,CAAC,EACvC,UAAU,EAAE,WAAW,CAAC,iBAAiB,EAAE,CAAC,GAC3C,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;IAoF7C,OAAO,CAAC,MAAM,CAAC,oBAAoB;CAsDpC"}
|
|
@@ -5,6 +5,7 @@ import { asKnownSize, FixedSizeArray } from "#@typeberry/collections";
|
|
|
5
5
|
import { HASH_SIZE } from "#@typeberry/hash";
|
|
6
6
|
import { Logger } from "#@typeberry/logger";
|
|
7
7
|
import { tryAsU8, tryAsU16, tryAsU32 } from "#@typeberry/numbers";
|
|
8
|
+
import { buildWorkPackageFetchData } from "#@typeberry/transition/externalities/fetch-externalities.js";
|
|
8
9
|
import { assertEmpty, Result } from "#@typeberry/utils";
|
|
9
10
|
import { AuthorizationError, IsAuthorized } from "./is-authorized.js";
|
|
10
11
|
import { Refine } from "./refine.js";
|
|
@@ -46,8 +47,7 @@ export class InCore {
|
|
|
46
47
|
*/
|
|
47
48
|
async refine(workPackageAndHash, core, imports, extrinsics) {
|
|
48
49
|
const workPackageHash = workPackageAndHash.hash;
|
|
49
|
-
const { context,
|
|
50
|
-
assertEmpty(rest);
|
|
50
|
+
const { context, items } = workPackageAndHash.data;
|
|
51
51
|
// TODO [ToDr] Verify BEEFY root
|
|
52
52
|
// TODO [ToDr] Verify prerequisites
|
|
53
53
|
logger.log `[core:${core}] Attempting to refine work package with ${items.length} items.`;
|
|
@@ -72,8 +72,10 @@ export class InCore {
|
|
|
72
72
|
if (lookupState.timeslot !== context.lookupAnchorSlot) {
|
|
73
73
|
return Result.error(RefineError.InvalidLookupAnchorSlot, () => `Lookup anchor slot does not match the one is state. Ours: ${lookupState.timeslot}, expected: ${context.lookupAnchorSlot}`);
|
|
74
74
|
}
|
|
75
|
+
// Eagerly build the per-package fetch data so we pay the encoding cost
|
|
76
|
+
const packageFetchData = buildWorkPackageFetchData(this.chainSpec, workPackageAndHash.data);
|
|
75
77
|
// Check authorization
|
|
76
|
-
const authResult = await this.isAuthorized.invoke(state, core,
|
|
78
|
+
const authResult = await this.isAuthorized.invoke(state, core, packageFetchData);
|
|
77
79
|
if (authResult.isError) {
|
|
78
80
|
return Result.error(RefineError.AuthorizationError, () => `Authorization error: ${AuthorizationError[authResult.error]}: ${authResult.details()}.`);
|
|
79
81
|
}
|
|
@@ -83,7 +85,7 @@ export class InCore {
|
|
|
83
85
|
const refineResults = [];
|
|
84
86
|
for (const [idx, item] of items.entries()) {
|
|
85
87
|
logger.info `[core:${core}][i:${idx}] Refining item for service ${item.service}.`;
|
|
86
|
-
const result = await this.refineItem.invoke(state, lookupState, idx, item, imports, extrinsics, core, workPackageHash, exportOffset);
|
|
88
|
+
const result = await this.refineItem.invoke(state, lookupState, packageFetchData, idx, item, imports, extrinsics, core, workPackageHash, exportOffset, authResult.ok.authorizationOutput);
|
|
87
89
|
refineResults.push(result);
|
|
88
90
|
exportOffset += result.exports.length;
|
|
89
91
|
}
|