@typeberry/lib 0.5.9 → 0.5.10-44bf91a
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/block.d.ts +3 -3
- package/packages/jam/block/header.d.ts +6 -6
- package/packages/jam/block/test-helpers.d.ts +2 -2
- package/packages/jam/block/tickets.d.ts +5 -6
- package/packages/jam/block/tickets.d.ts.map +1 -1
- package/packages/jam/block/tickets.js +2 -10
- package/packages/jam/block/work-item-segment.d.ts +23 -6
- package/packages/jam/block/work-item-segment.d.ts.map +1 -1
- package/packages/jam/block/work-item-segment.js +24 -7
- package/packages/jam/block/work-item.d.ts +3 -3
- package/packages/jam/block/work-item.d.ts.map +1 -1
- package/packages/jam/block/work-item.js +7 -3
- package/packages/jam/block/work-package.d.ts +2 -2
- package/packages/jam/block/work-package.d.ts.map +1 -1
- package/packages/jam/block/work-package.js +2 -6
- package/packages/jam/block-json/block.d.ts +2 -2
- package/packages/jam/block-json/block.js +1 -1
- package/packages/jam/block-json/common.d.ts +1 -2
- package/packages/jam/block-json/common.d.ts.map +1 -1
- package/packages/jam/block-json/common.js +2 -2
- package/packages/jam/block-json/extrinsic.js +1 -1
- package/packages/jam/block-json/header.d.ts +1 -2
- package/packages/jam/block-json/header.d.ts.map +1 -1
- package/packages/jam/block-json/header.js +32 -34
- package/packages/jam/block-json/tickets-extrinsic.d.ts +1 -2
- package/packages/jam/block-json/tickets-extrinsic.d.ts.map +1 -1
- package/packages/jam/block-json/tickets-extrinsic.js +5 -7
- package/packages/jam/block-json/work-result.js +2 -2
- package/packages/jam/database/blocks.d.ts +3 -0
- package/packages/jam/database/blocks.d.ts.map +1 -1
- package/packages/jam/database/blocks.js +5 -0
- package/packages/jam/database-lmdb/blocks.d.ts +1 -0
- package/packages/jam/database-lmdb/blocks.d.ts.map +1 -1
- package/packages/jam/database-lmdb/blocks.js +5 -0
- package/packages/jam/database-lmdb/states.js +1 -1
- package/packages/jam/executor/pvm-executor.d.ts +2 -2
- package/packages/jam/executor/pvm-executor.d.ts.map +1 -1
- package/packages/jam/fuzz-proto/v1/types.d.ts +1 -1
- package/packages/jam/in-core/externalities/refine.d.ts +42 -11
- package/packages/jam/in-core/externalities/refine.d.ts.map +1 -1
- package/packages/jam/in-core/externalities/refine.js +95 -11
- package/packages/jam/in-core/externalities/refine.test.d.ts +2 -0
- package/packages/jam/in-core/externalities/refine.test.d.ts.map +1 -0
- package/packages/jam/in-core/externalities/refine.test.js +263 -0
- package/packages/jam/in-core/in-core.d.ts +1 -1
- package/packages/jam/in-core/in-core.d.ts.map +1 -1
- package/packages/jam/in-core/in-core.js +17 -10
- 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 +3 -1
- package/packages/jam/jam-host-calls/externalities/refine-externalities.d.ts.map +1 -1
- package/packages/jam/jam-host-calls/externalities/refine-externalities.test.d.ts +2 -0
- package/packages/jam/jam-host-calls/externalities/refine-externalities.test.d.ts.map +1 -1
- package/packages/jam/jam-host-calls/externalities/refine-externalities.test.js +5 -0
- package/packages/jam/jam-host-calls/general/fetch.d.ts +159 -98
- package/packages/jam/jam-host-calls/general/fetch.d.ts.map +1 -1
- package/packages/jam/jam-host-calls/general/fetch.js +110 -16
- package/packages/jam/jam-host-calls/general/fetch.test.js +87 -56
- package/packages/jam/jam-host-calls/refine/export.d.ts +1 -1
- package/packages/jam/jam-host-calls/refine/export.js +1 -1
- package/packages/jam/jam-host-calls/refine/export.test.js +3 -0
- package/packages/jam/jam-host-calls/refine/historical-lookup.d.ts +1 -1
- package/packages/jam/jam-host-calls/refine/historical-lookup.js +1 -1
- package/packages/jam/jamnp-s/protocol/ce-131-ce-132-safrole-ticket-distribution.d.ts +1 -1
- package/packages/jam/jamnp-s/protocol/ce-131-ce-132-safrole-ticket-distribution.test.js +1 -1
- package/packages/jam/jamnp-s/protocol/ce-133-work-package-submission.d.ts +1 -1
- package/packages/jam/jamnp-s/protocol/up-0-block-announcement.d.ts +1 -1
- package/packages/jam/jamnp-s/tasks/ticket-distribution.test.js +1 -1
- package/packages/jam/node/main-fuzz.d.ts.map +1 -1
- package/packages/jam/node/main-fuzz.js +1 -0
- package/packages/jam/node/main-importer.d.ts +1 -0
- package/packages/jam/node/main-importer.d.ts.map +1 -1
- package/packages/jam/node/main-importer.js +1 -0
- package/packages/jam/node/main.d.ts.map +1 -1
- package/packages/jam/node/main.js +1 -0
- package/packages/jam/node/reader.d.ts +2 -2
- package/packages/jam/node/workers.d.ts +22 -22
- package/packages/jam/safrole/bandersnatch-vrf.d.ts +1 -2
- package/packages/jam/safrole/bandersnatch-vrf.d.ts.map +1 -1
- package/packages/jam/safrole/bandersnatch-vrf.js +2 -2
- package/packages/jam/safrole/bandersnatch-vrf.test.js +2 -3
- package/packages/jam/safrole/safrole.test.js +72 -80
- package/packages/jam/state/safrole-data.d.ts +1 -1
- package/packages/jam/state/test.utils.js +1 -1
- package/packages/jam/state-json/dump.js +2 -2
- package/packages/jam/state-json/safrole.d.ts +2 -2
- package/packages/jam/state-json/safrole.d.ts.map +1 -1
- package/packages/jam/state-json/safrole.js +4 -4
- package/packages/jam/state-merkleization/in-memory-state-codec.d.ts +1 -1
- package/packages/jam/state-vectors/index.d.ts +7 -8
- package/packages/jam/state-vectors/index.d.ts.map +1 -1
- package/packages/jam/state-vectors/index.js +4 -6
- 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 +2 -0
- package/packages/jam/transition/externalities/index.d.ts.map +1 -1
- package/packages/jam/transition/externalities/index.js +2 -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 +48 -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/hasher.test.js +1 -1
- package/packages/workers/block-authorship/main.d.ts.map +1 -1
- package/packages/workers/block-authorship/main.js +1 -1
- package/packages/workers/block-authorship/protocol.d.ts +4 -4
- package/packages/workers/block-authorship/ticket-generator.d.ts +1 -2
- package/packages/workers/block-authorship/ticket-generator.d.ts.map +1 -1
- package/packages/workers/block-authorship/ticket-generator.js +2 -2
- package/packages/workers/block-authorship/ticket-generator.test.js +10 -11
- package/packages/workers/comms-authorship-network/protocol.d.ts +1 -1
- package/packages/workers/comms-authorship-network/tickets-message.d.ts +1 -1
- package/packages/workers/importer/importer.d.ts +1 -0
- package/packages/workers/importer/importer.d.ts.map +1 -1
- package/packages/workers/importer/importer.js +7 -2
- package/packages/workers/importer/main.d.ts.map +1 -1
- package/packages/workers/importer/main.js +2 -0
- package/packages/workers/importer/protocol.d.ts +12 -9
- package/packages/workers/importer/protocol.d.ts.map +1 -1
- package/packages/workers/importer/protocol.js +8 -3
- package/packages/workers/jam-network/protocol.d.ts +10 -10
- 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
|
@@ -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) {
|
|
@@ -6,7 +6,7 @@ import { asKnownSize, FixedSizeArray, HashDictionary } from "#@typeberry/collect
|
|
|
6
6
|
import { tinyChainSpec } from "#@typeberry/config";
|
|
7
7
|
import { BANDERSNATCH_KEY_BYTES, BLS_KEY_BYTES, ED25519_KEY_BYTES } from "#@typeberry/crypto";
|
|
8
8
|
import { Blake2b, HASH_SIZE } from "#@typeberry/hash";
|
|
9
|
-
import { EjectError, ForgetPreimageError, NewServiceError, PartiallyUpdatedState, PendingTransfer, PreimageStatusKind, ProvidePreimageError, RequestPreimageError, TRANSFER_MEMO_BYTES, TransferError, UnprivilegedError, UpdatePrivilegesError, writeServiceIdAsLeBytes, } from "#@typeberry/jam-host-calls";
|
|
9
|
+
import { CURRENT_SERVICE_ID, EjectError, ForgetPreimageError, NewServiceError, PartiallyUpdatedState, PendingTransfer, PreimageStatusKind, ProvidePreimageError, RequestPreimageError, TRANSFER_MEMO_BYTES, TransferError, UnprivilegedError, UpdatePrivilegesError, writeServiceIdAsLeBytes, } from "#@typeberry/jam-host-calls";
|
|
10
10
|
import { tryAsU32, tryAsU64 } from "#@typeberry/numbers";
|
|
11
11
|
import { AUTHORIZATION_QUEUE_SIZE, InMemoryService, InMemoryState, LookupHistoryItem, PreimageItem, PrivilegedServices, ServiceAccountInfo, StorageItem, tryAsLookupHistorySlots, tryAsPerCore, UpdatePreimage, UpdateService, VALIDATOR_META_BYTES, ValidatorData, } from "#@typeberry/state";
|
|
12
12
|
import { testState } from "#@typeberry/state/test.utils.js";
|
|
@@ -663,16 +663,28 @@ describe("PartialState.upgradeService", () => {
|
|
|
663
663
|
});
|
|
664
664
|
});
|
|
665
665
|
describe("PartialState.updateAuthorizationQueue", () => {
|
|
666
|
-
it("should update the authorization queue for
|
|
666
|
+
it("should update the authorization queue and transfer the assigner for the given core", () => {
|
|
667
667
|
const state = partiallyUpdatedState();
|
|
668
|
+
const initialPrivileged = state.state.privilegedServices;
|
|
668
669
|
const partialState = new AccumulateExternalities(tinyChainSpec, blake2b, state, tryAsServiceId(0), tryAsServiceId(10), tryAsTimeSlot(16));
|
|
669
670
|
const coreIndex = tryAsCoreIndex(0);
|
|
670
|
-
const
|
|
671
|
+
const newAssigner = tryAsServiceId(99);
|
|
671
672
|
const queue = FixedSizeArray.new(Array.from({ length: AUTHORIZATION_QUEUE_SIZE }, () => Bytes.fill(HASH_SIZE, 0xee).asOpaque()), AUTHORIZATION_QUEUE_SIZE);
|
|
672
673
|
// when
|
|
673
|
-
partialState.updateAuthorizationQueue(coreIndex, queue,
|
|
674
|
+
const result = partialState.updateAuthorizationQueue(coreIndex, queue, newAssigner);
|
|
674
675
|
// then
|
|
676
|
+
deepEqual(result, Result.ok(OK));
|
|
675
677
|
assert.deepStrictEqual(state.stateUpdate.authorizationQueues.get(coreIndex), queue);
|
|
678
|
+
// the privilegedServices update must be written, with only the targeted
|
|
679
|
+
// core's assigner transferred; all other fields must be preserved.
|
|
680
|
+
const updated = state.stateUpdate.privilegedServices;
|
|
681
|
+
assert.ok(updated !== null, "stateUpdate.privilegedServices should be written");
|
|
682
|
+
assert.strictEqual(updated.assigners[0], newAssigner);
|
|
683
|
+
assert.strictEqual(updated.assigners[1], initialPrivileged.assigners[1]);
|
|
684
|
+
assert.strictEqual(updated.manager, initialPrivileged.manager);
|
|
685
|
+
assert.strictEqual(updated.delegator, initialPrivileged.delegator);
|
|
686
|
+
assert.strictEqual(updated.registrar, initialPrivileged.registrar);
|
|
687
|
+
assert.strictEqual(updated.autoAccumulateServices, initialPrivileged.autoAccumulateServices);
|
|
676
688
|
});
|
|
677
689
|
it("should return InvalidServiceId when given auth manager is invalid", () => {
|
|
678
690
|
const state = partiallyUpdatedState();
|
|
@@ -685,6 +697,8 @@ describe("PartialState.updateAuthorizationQueue", () => {
|
|
|
685
697
|
// then
|
|
686
698
|
deepEqual(result, Result.error(UpdatePrivilegesError.InvalidServiceId, () => "New auth manager is null for core 0"));
|
|
687
699
|
assert.deepStrictEqual(state.stateUpdate.authorizationQueues.get(coreIndex), undefined);
|
|
700
|
+
// no partial privilegedServices write on error
|
|
701
|
+
assert.strictEqual(state.stateUpdate.privilegedServices, null);
|
|
688
702
|
});
|
|
689
703
|
it("should return UnprivilegedService when current service is not privileged", () => {
|
|
690
704
|
const state = partiallyUpdatedState();
|
|
@@ -701,6 +715,8 @@ describe("PartialState.updateAuthorizationQueue", () => {
|
|
|
701
715
|
// then
|
|
702
716
|
deepEqual(result, Result.error(UpdatePrivilegesError.UnprivilegedService, () => "Service 0 not assigner for core 0 (expected: 1)"));
|
|
703
717
|
assert.deepStrictEqual(state.stateUpdate.authorizationQueues.get(coreIndex), undefined);
|
|
718
|
+
// no partial privilegedServices write on error
|
|
719
|
+
assert.strictEqual(state.stateUpdate.privilegedServices, null);
|
|
704
720
|
});
|
|
705
721
|
it("should return UnprivilegedService before InvalidServiceId if given auth manager is incorrect, but current servis is also unprivileged", () => {
|
|
706
722
|
const state = partiallyUpdatedState();
|
|
@@ -717,6 +733,60 @@ describe("PartialState.updateAuthorizationQueue", () => {
|
|
|
717
733
|
// then
|
|
718
734
|
deepEqual(result, Result.error(UpdatePrivilegesError.UnprivilegedService, () => "Service 0 not assigner for core 0 (expected: 1)"));
|
|
719
735
|
assert.deepStrictEqual(state.stateUpdate.authorizationQueues.get(coreIndex), undefined);
|
|
736
|
+
// no partial privilegedServices write on error
|
|
737
|
+
assert.strictEqual(state.stateUpdate.privilegedServices, null);
|
|
738
|
+
});
|
|
739
|
+
it("should succeed on a self-transfer using CURRENT_SERVICE_ID", () => {
|
|
740
|
+
const state = partiallyUpdatedState();
|
|
741
|
+
// inject a service info for CURRENT_SERVICE_ID so it can act as the
|
|
742
|
+
// current (and assigning) service on core 0
|
|
743
|
+
const baseService = state.state.services.get(tryAsServiceId(0));
|
|
744
|
+
if (baseService === undefined) {
|
|
745
|
+
throw new Error("Invalid service!");
|
|
746
|
+
}
|
|
747
|
+
state.state.services.set(CURRENT_SERVICE_ID, new InMemoryService(CURRENT_SERVICE_ID, {
|
|
748
|
+
info: baseService.data.info,
|
|
749
|
+
preimages: HashDictionary.new(),
|
|
750
|
+
lookupHistory: HashDictionary.new(),
|
|
751
|
+
storage: new Map(),
|
|
752
|
+
}));
|
|
753
|
+
state.state.privilegedServices = PrivilegedServices.create({
|
|
754
|
+
...state.state.privilegedServices,
|
|
755
|
+
assigners: asOpaqueType(FixedSizeArray.new([CURRENT_SERVICE_ID, tryAsServiceId(0)], tinyChainSpec.coresCount)),
|
|
756
|
+
});
|
|
757
|
+
const partialState = new AccumulateExternalities(tinyChainSpec, blake2b, state, CURRENT_SERVICE_ID, tryAsServiceId(10), tryAsTimeSlot(16));
|
|
758
|
+
const coreIndex = tryAsCoreIndex(0);
|
|
759
|
+
const queue = FixedSizeArray.new(Array.from({ length: AUTHORIZATION_QUEUE_SIZE }, () => Bytes.fill(HASH_SIZE, 0xee).asOpaque()), AUTHORIZATION_QUEUE_SIZE);
|
|
760
|
+
// when
|
|
761
|
+
const result = partialState.updateAuthorizationQueue(coreIndex, queue, CURRENT_SERVICE_ID);
|
|
762
|
+
// then
|
|
763
|
+
deepEqual(result, Result.ok(OK));
|
|
764
|
+
assert.deepStrictEqual(state.stateUpdate.authorizationQueues.get(coreIndex), queue);
|
|
765
|
+
const updated = state.stateUpdate.privilegedServices;
|
|
766
|
+
assert.ok(updated !== null, "stateUpdate.privilegedServices should be written");
|
|
767
|
+
assert.strictEqual(updated.assigners[0], CURRENT_SERVICE_ID);
|
|
768
|
+
assert.strictEqual(updated.assigners[1], tryAsServiceId(0));
|
|
769
|
+
});
|
|
770
|
+
it("should prevent the previous assigner from re-assigning after transfer", () => {
|
|
771
|
+
const state = partiallyUpdatedState();
|
|
772
|
+
const partialState = new AccumulateExternalities(tinyChainSpec, blake2b, state, tryAsServiceId(0), tryAsServiceId(10), tryAsTimeSlot(16));
|
|
773
|
+
const coreIndex = tryAsCoreIndex(0);
|
|
774
|
+
const newAssigner = tryAsServiceId(99);
|
|
775
|
+
const firstQueue = FixedSizeArray.new(Array.from({ length: AUTHORIZATION_QUEUE_SIZE }, () => Bytes.fill(HASH_SIZE, 0xee).asOpaque()), AUTHORIZATION_QUEUE_SIZE);
|
|
776
|
+
const secondQueue = FixedSizeArray.new(Array.from({ length: AUTHORIZATION_QUEUE_SIZE }, () => Bytes.fill(HASH_SIZE, 0xff).asOpaque()), AUTHORIZATION_QUEUE_SIZE);
|
|
777
|
+
// when: first call succeeds and transfers the assigner to service 99
|
|
778
|
+
const first = partialState.updateAuthorizationQueue(coreIndex, firstQueue, newAssigner);
|
|
779
|
+
// and the previous assigner (service 0) immediately tries to re-assign
|
|
780
|
+
const second = partialState.updateAuthorizationQueue(coreIndex, secondQueue, tryAsServiceId(0));
|
|
781
|
+
// then
|
|
782
|
+
deepEqual(first, Result.ok(OK));
|
|
783
|
+
deepEqual(second, Result.error(UpdatePrivilegesError.UnprivilegedService, () => "Service 0 not assigner for core 0 (expected: 99)"));
|
|
784
|
+
// the first queue remains — the failing second call must not overwrite it
|
|
785
|
+
assert.deepStrictEqual(state.stateUpdate.authorizationQueues.get(coreIndex), firstQueue);
|
|
786
|
+
// and the transferred assigner is still in place
|
|
787
|
+
const updated = state.stateUpdate.privilegedServices;
|
|
788
|
+
assert.ok(updated !== null);
|
|
789
|
+
assert.strictEqual(updated.assigners[0], newAssigner);
|
|
720
790
|
});
|
|
721
791
|
});
|
|
722
792
|
describe("PartialState.updatePrivilegedServices", () => {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { EntropyHash } from "#@typeberry/block";
|
|
2
|
+
import type { BytesBlob } from "#@typeberry/bytes";
|
|
3
|
+
import type { ChainSpec } from "#@typeberry/config";
|
|
4
|
+
import { general, type PendingTransfer } from "#@typeberry/jam-host-calls";
|
|
5
|
+
import type { U64 } from "#@typeberry/numbers";
|
|
6
|
+
import type { Operand } from "../accumulate/operand.js";
|
|
7
|
+
export declare class AccumulateFetchExternalities implements general.IAccumulateFetch {
|
|
8
|
+
private readonly entropyHash;
|
|
9
|
+
private readonly transfers;
|
|
10
|
+
private readonly operands;
|
|
11
|
+
private readonly chainSpec;
|
|
12
|
+
readonly context = general.FetchContext.Accumulate;
|
|
13
|
+
constructor(entropyHash: EntropyHash, transfers: PendingTransfer[], operands: Operand[], chainSpec: ChainSpec);
|
|
14
|
+
constants(): BytesBlob;
|
|
15
|
+
entropy(): EntropyHash;
|
|
16
|
+
allTransfersAndOperands(): BytesBlob | null;
|
|
17
|
+
oneTransferOrOperand(index: U64): BytesBlob | null;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=accumulate-fetch-externalities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accumulate-fetch-externalities.d.ts","sourceRoot":"","sources":["../../../../../../packages/jam/transition/externalities/accumulate-fetch-externalities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC1E,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AASxD,qBAAa,4BAA6B,YAAW,OAAO,CAAC,gBAAgB;IAIzE,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAN5B,QAAQ,CAAC,OAAO,mCAAmC;gBAGhC,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,eAAe,EAAE,EAC5B,QAAQ,EAAE,OAAO,EAAE,EACnB,SAAS,EAAE,SAAS;IAGvC,SAAS,IAAI,SAAS;IAItB,OAAO,IAAI,WAAW;IAItB,uBAAuB,IAAI,SAAS,GAAG,IAAI;IAU3C,oBAAoB,CAAC,KAAK,EAAE,GAAG,GAAG,SAAS,GAAG,IAAI;CAqBnD"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Encoder } from "#@typeberry/codec";
|
|
2
|
+
import { general } from "#@typeberry/jam-host-calls";
|
|
3
|
+
import { getEncodedConstants, TRANSFER_OR_OPERAND, TRANSFERS_AND_OPERANDS, TransferOperandKind, } from "./fetch-externalities.js";
|
|
4
|
+
export class AccumulateFetchExternalities {
|
|
5
|
+
entropyHash;
|
|
6
|
+
transfers;
|
|
7
|
+
operands;
|
|
8
|
+
chainSpec;
|
|
9
|
+
context = general.FetchContext.Accumulate;
|
|
10
|
+
constructor(entropyHash, transfers, operands, chainSpec) {
|
|
11
|
+
this.entropyHash = entropyHash;
|
|
12
|
+
this.transfers = transfers;
|
|
13
|
+
this.operands = operands;
|
|
14
|
+
this.chainSpec = chainSpec;
|
|
15
|
+
}
|
|
16
|
+
constants() {
|
|
17
|
+
return getEncodedConstants(this.chainSpec);
|
|
18
|
+
}
|
|
19
|
+
entropy() {
|
|
20
|
+
return this.entropyHash;
|
|
21
|
+
}
|
|
22
|
+
allTransfersAndOperands() {
|
|
23
|
+
const transfersAndOperands = this.transfers
|
|
24
|
+
.map((transfer) => ({ kind: TransferOperandKind.TRANSFER, value: transfer }))
|
|
25
|
+
.concat(this.operands.map((operand) => ({ kind: TransferOperandKind.OPERAND, value: operand })));
|
|
26
|
+
return Encoder.encodeObject(TRANSFERS_AND_OPERANDS, transfersAndOperands, this.chainSpec);
|
|
27
|
+
}
|
|
28
|
+
oneTransferOrOperand(index) {
|
|
29
|
+
if (index >= this.transfers.length + this.operands.length) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
// Transfers-first ordering, consistent with allTransfersAndOperands()
|
|
33
|
+
const kind = index < this.transfers.length ? TransferOperandKind.TRANSFER : TransferOperandKind.OPERAND;
|
|
34
|
+
const transferOrOperand = kind === TransferOperandKind.TRANSFER
|
|
35
|
+
? { kind: TransferOperandKind.TRANSFER, value: this.transfers[Number(index)] }
|
|
36
|
+
: {
|
|
37
|
+
kind: TransferOperandKind.OPERAND,
|
|
38
|
+
value: this.operands[Number(index) - this.transfers.length],
|
|
39
|
+
};
|
|
40
|
+
if (transferOrOperand.value === undefined) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
return Encoder.encodeObject(TRANSFER_OR_OPERAND, transferOrOperand, this.chainSpec);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accumulate-fetch-externalities.test.d.ts","sourceRoot":"","sources":["../../../../../../packages/jam/transition/externalities/accumulate-fetch-externalities.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import assert from "node:assert";
|
|
2
|
+
import { describe, it } from "node:test";
|
|
3
|
+
import { tryAsServiceGas, tryAsServiceId } from "#@typeberry/block";
|
|
4
|
+
import { WorkExecResult } from "#@typeberry/block/work-result.js";
|
|
5
|
+
import { Bytes, BytesBlob } from "#@typeberry/bytes";
|
|
6
|
+
import { codec, Encoder } from "#@typeberry/codec";
|
|
7
|
+
import { fullChainSpec, tinyChainSpec } from "#@typeberry/config";
|
|
8
|
+
import { HASH_SIZE } from "#@typeberry/hash";
|
|
9
|
+
import { TRANSFER_MEMO_BYTES } from "#@typeberry/jam-host-calls/externalities/partial-state.js";
|
|
10
|
+
import { PendingTransfer } from "#@typeberry/jam-host-calls/externalities/pending-transfer.js";
|
|
11
|
+
import { tryAsU64 } from "#@typeberry/numbers";
|
|
12
|
+
import { Operand } from "../accumulate/operand.js";
|
|
13
|
+
import { AccumulateFetchExternalities } from "./accumulate-fetch-externalities.js";
|
|
14
|
+
import { TRANSFER_OR_OPERAND, TransferOperandKind } from "./fetch-externalities.js";
|
|
15
|
+
describe("AccumulateFetchExternalities", () => {
|
|
16
|
+
const prepareOperands = (length) => {
|
|
17
|
+
const operands = [];
|
|
18
|
+
for (let i = 0; i < length; i++) {
|
|
19
|
+
operands.push(Operand.create({
|
|
20
|
+
authorizationOutput: BytesBlob.empty(),
|
|
21
|
+
authorizerHash: Bytes.fill(HASH_SIZE, i + 1).asOpaque(),
|
|
22
|
+
exportsRoot: Bytes.fill(HASH_SIZE, i + 2).asOpaque(),
|
|
23
|
+
hash: Bytes.fill(HASH_SIZE, i + 4).asOpaque(),
|
|
24
|
+
payloadHash: Bytes.fill(HASH_SIZE, i + 5).asOpaque(),
|
|
25
|
+
result: WorkExecResult.ok(BytesBlob.empty()),
|
|
26
|
+
gas: tryAsServiceGas(1_000),
|
|
27
|
+
}));
|
|
28
|
+
}
|
|
29
|
+
return operands;
|
|
30
|
+
};
|
|
31
|
+
const prepareTransfers = (length) => {
|
|
32
|
+
const transfers = [];
|
|
33
|
+
for (let i = 0; i < length; i++) {
|
|
34
|
+
transfers.push(PendingTransfer.create({
|
|
35
|
+
amount: tryAsU64(1000),
|
|
36
|
+
source: tryAsServiceId(i),
|
|
37
|
+
destination: tryAsServiceId(i + 1),
|
|
38
|
+
gas: tryAsServiceGas(10),
|
|
39
|
+
memo: Bytes.fill(TRANSFER_MEMO_BYTES, 0),
|
|
40
|
+
}));
|
|
41
|
+
}
|
|
42
|
+
return transfers;
|
|
43
|
+
};
|
|
44
|
+
// allTransfersAndOperands: transfers first, then operands
|
|
45
|
+
const toAllTransfersAndOperands = (operands, transfers) => {
|
|
46
|
+
return [
|
|
47
|
+
...transfers.map((t) => ({ kind: TransferOperandKind.TRANSFER, value: t })),
|
|
48
|
+
...operands.map((o) => ({ kind: TransferOperandKind.OPERAND, value: o })),
|
|
49
|
+
];
|
|
50
|
+
};
|
|
51
|
+
// oneTransferOrOperand: transfers first, then operands (same as allTransfersAndOperands)
|
|
52
|
+
const toOneTransferOrOperandAt = (operands, transfers, index) => {
|
|
53
|
+
if (index >= transfers.length + operands.length) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
if (index < transfers.length) {
|
|
57
|
+
return { kind: TransferOperandKind.TRANSFER, value: transfers[index] };
|
|
58
|
+
}
|
|
59
|
+
return { kind: TransferOperandKind.OPERAND, value: operands[index - transfers.length] };
|
|
60
|
+
};
|
|
61
|
+
const encodeOneTransferOrOperand = (item, chainSpec) => {
|
|
62
|
+
if (item === null) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
return Encoder.encodeObject(TRANSFER_OR_OPERAND, item, chainSpec);
|
|
66
|
+
};
|
|
67
|
+
const prepareAccumulateData = ({ chainSpec, operands, entropy, transfers, }) => {
|
|
68
|
+
const defaultChainSpec = tinyChainSpec;
|
|
69
|
+
const defaultEntropy = Bytes.zero(HASH_SIZE).asOpaque();
|
|
70
|
+
const defaultOperands = [];
|
|
71
|
+
const defaultTransfers = [];
|
|
72
|
+
return new AccumulateFetchExternalities(entropy ?? defaultEntropy, transfers ?? defaultTransfers, operands ?? defaultOperands, chainSpec ?? defaultChainSpec);
|
|
73
|
+
};
|
|
74
|
+
it("should return different constants for different chain specs", () => {
|
|
75
|
+
const tinyFetchExternalities = prepareAccumulateData({ chainSpec: tinyChainSpec });
|
|
76
|
+
const fullFetchExternalities = prepareAccumulateData({ chainSpec: fullChainSpec });
|
|
77
|
+
const tinyConstants = tinyFetchExternalities.constants();
|
|
78
|
+
const fullConstants = fullFetchExternalities.constants();
|
|
79
|
+
assert.notStrictEqual(tinyConstants.length, 0);
|
|
80
|
+
assert.notStrictEqual(fullConstants.length, 0);
|
|
81
|
+
assert.notDeepStrictEqual(tinyConstants, fullConstants);
|
|
82
|
+
});
|
|
83
|
+
it("should return entropy hash", () => {
|
|
84
|
+
const expectedEntropy = Bytes.fill(HASH_SIZE, 5).asOpaque();
|
|
85
|
+
const fetchExternalities = prepareAccumulateData({ entropy: expectedEntropy });
|
|
86
|
+
const entropy = fetchExternalities.entropy();
|
|
87
|
+
assert.deepStrictEqual(entropy, expectedEntropy);
|
|
88
|
+
});
|
|
89
|
+
it("should return all transfers and operands", () => {
|
|
90
|
+
const operands = prepareOperands(3);
|
|
91
|
+
const transfers = prepareTransfers(2);
|
|
92
|
+
const chainSpec = tinyChainSpec;
|
|
93
|
+
const expected = toAllTransfersAndOperands(operands, transfers);
|
|
94
|
+
const encodedExpected = Encoder.encodeObject(codec.sequenceVarLen(TRANSFER_OR_OPERAND), expected, chainSpec);
|
|
95
|
+
const fetchExternalities = prepareAccumulateData({ operands, transfers, chainSpec });
|
|
96
|
+
const result = fetchExternalities.allTransfersAndOperands();
|
|
97
|
+
assert.deepStrictEqual(result, encodedExpected);
|
|
98
|
+
});
|
|
99
|
+
it("should return empty encoded sequence when no transfers and no operands", () => {
|
|
100
|
+
const chainSpec = tinyChainSpec;
|
|
101
|
+
const encodedExpected = Encoder.encodeObject(codec.sequenceVarLen(TRANSFER_OR_OPERAND), [], chainSpec);
|
|
102
|
+
const fetchExternalities = prepareAccumulateData({ operands: [], transfers: [], chainSpec });
|
|
103
|
+
const result = fetchExternalities.allTransfersAndOperands();
|
|
104
|
+
assert.deepStrictEqual(result, encodedExpected);
|
|
105
|
+
});
|
|
106
|
+
it("should return one transfer by index (first range)", () => {
|
|
107
|
+
const operands = prepareOperands(3);
|
|
108
|
+
const transfers = prepareTransfers(2);
|
|
109
|
+
const chainSpec = tinyChainSpec;
|
|
110
|
+
const encodedExpected = encodeOneTransferOrOperand(toOneTransferOrOperandAt(operands, transfers, 0), chainSpec);
|
|
111
|
+
const fetchExternalities = prepareAccumulateData({ operands, transfers, chainSpec });
|
|
112
|
+
// Transfers come first (indices 0..1), then operands (indices 2..4)
|
|
113
|
+
const result = fetchExternalities.oneTransferOrOperand(tryAsU64(0));
|
|
114
|
+
assert.deepStrictEqual(result, encodedExpected);
|
|
115
|
+
});
|
|
116
|
+
it("should return one operand by index (second range)", () => {
|
|
117
|
+
const operands = prepareOperands(3);
|
|
118
|
+
const transfers = prepareTransfers(2);
|
|
119
|
+
const chainSpec = tinyChainSpec;
|
|
120
|
+
const encodedExpected = encodeOneTransferOrOperand(toOneTransferOrOperandAt(operands, transfers, 2), chainSpec);
|
|
121
|
+
const fetchExternalities = prepareAccumulateData({ operands, transfers, chainSpec });
|
|
122
|
+
// Operands start after transfers, so index 2 is the first operand
|
|
123
|
+
const result = fetchExternalities.oneTransferOrOperand(tryAsU64(2));
|
|
124
|
+
assert.deepStrictEqual(result, encodedExpected);
|
|
125
|
+
});
|
|
126
|
+
it("should return null when index is out of bounds", () => {
|
|
127
|
+
const operands = prepareOperands(3);
|
|
128
|
+
const transfers = prepareTransfers(2);
|
|
129
|
+
const chainSpec = tinyChainSpec;
|
|
130
|
+
const fetchExternalities = prepareAccumulateData({ operands, transfers, chainSpec });
|
|
131
|
+
// Total items: 3 operands + 2 transfers = 5, so index 5 is out of bounds
|
|
132
|
+
const result = fetchExternalities.oneTransferOrOperand(tryAsU64(5));
|
|
133
|
+
assert.strictEqual(result, null);
|
|
134
|
+
});
|
|
135
|
+
it("should return null when index is far out of bounds", () => {
|
|
136
|
+
const operands = prepareOperands(3);
|
|
137
|
+
const transfers = prepareTransfers(2);
|
|
138
|
+
const chainSpec = tinyChainSpec;
|
|
139
|
+
const fetchExternalities = prepareAccumulateData({ operands, transfers, chainSpec });
|
|
140
|
+
const result = fetchExternalities.oneTransferOrOperand(tryAsU64(153));
|
|
141
|
+
assert.strictEqual(result, null);
|
|
142
|
+
});
|
|
143
|
+
it("should have consistent encoding between all and one", () => {
|
|
144
|
+
const operands = prepareOperands(2);
|
|
145
|
+
const transfers = prepareTransfers(2);
|
|
146
|
+
const chainSpec = tinyChainSpec;
|
|
147
|
+
const allItems = toAllTransfersAndOperands(operands, transfers);
|
|
148
|
+
const encodedAll = Encoder.encodeObject(codec.sequenceVarLen(TRANSFER_OR_OPERAND), allItems, chainSpec);
|
|
149
|
+
const fetchExternalities = prepareAccumulateData({ operands, transfers, chainSpec });
|
|
150
|
+
const all = fetchExternalities.allTransfersAndOperands();
|
|
151
|
+
assert.deepStrictEqual(all, encodedAll);
|
|
152
|
+
for (let i = 0; i < operands.length + transfers.length; i++) {
|
|
153
|
+
const one = fetchExternalities.oneTransferOrOperand(tryAsU64(i));
|
|
154
|
+
const encodedOne = encodeOneTransferOrOperand(toOneTransferOrOperandAt(operands, transfers, i), chainSpec);
|
|
155
|
+
assert.deepStrictEqual(one, encodedOne, `Mismatch at index ${i}`);
|
|
156
|
+
}
|
|
157
|
+
const outOfRange = fetchExternalities.oneTransferOrOperand(tryAsU64(operands.length + transfers.length));
|
|
158
|
+
assert.strictEqual(outOfRange, null);
|
|
159
|
+
});
|
|
160
|
+
it("should handle only operands without transfers", () => {
|
|
161
|
+
const operands = prepareOperands(5);
|
|
162
|
+
const chainSpec = tinyChainSpec;
|
|
163
|
+
const allItems = toAllTransfersAndOperands(operands, []);
|
|
164
|
+
const encodedAll = Encoder.encodeObject(codec.sequenceVarLen(TRANSFER_OR_OPERAND), allItems, chainSpec);
|
|
165
|
+
const fetchExternalities = prepareAccumulateData({ operands, transfers: [], chainSpec });
|
|
166
|
+
const result = fetchExternalities.allTransfersAndOperands();
|
|
167
|
+
assert.deepStrictEqual(result, encodedAll);
|
|
168
|
+
for (let i = 0; i < operands.length; i++) {
|
|
169
|
+
const one = fetchExternalities.oneTransferOrOperand(tryAsU64(i));
|
|
170
|
+
const encodedOne = encodeOneTransferOrOperand(toOneTransferOrOperandAt(operands, [], i), chainSpec);
|
|
171
|
+
assert.deepStrictEqual(one, encodedOne, `Mismatch at operand index ${i}`);
|
|
172
|
+
}
|
|
173
|
+
const outOfRange = fetchExternalities.oneTransferOrOperand(tryAsU64(operands.length));
|
|
174
|
+
assert.strictEqual(outOfRange, null);
|
|
175
|
+
});
|
|
176
|
+
it("should handle only transfers without operands", () => {
|
|
177
|
+
const transfers = prepareTransfers(5);
|
|
178
|
+
const chainSpec = tinyChainSpec;
|
|
179
|
+
const allItems = toAllTransfersAndOperands([], transfers);
|
|
180
|
+
const encodedAll = Encoder.encodeObject(codec.sequenceVarLen(TRANSFER_OR_OPERAND), allItems, chainSpec);
|
|
181
|
+
const fetchExternalities = prepareAccumulateData({ operands: [], transfers, chainSpec });
|
|
182
|
+
const result = fetchExternalities.allTransfersAndOperands();
|
|
183
|
+
assert.deepStrictEqual(result, encodedAll);
|
|
184
|
+
for (let i = 0; i < transfers.length; i++) {
|
|
185
|
+
const one = fetchExternalities.oneTransferOrOperand(tryAsU64(i));
|
|
186
|
+
const encodedOne = encodeOneTransferOrOperand(toOneTransferOrOperandAt([], transfers, i), chainSpec);
|
|
187
|
+
assert.deepStrictEqual(one, encodedOne, `Mismatch at transfer index ${i}`);
|
|
188
|
+
}
|
|
189
|
+
const outOfRange = fetchExternalities.oneTransferOrOperand(tryAsU64(transfers.length));
|
|
190
|
+
assert.strictEqual(outOfRange, null);
|
|
191
|
+
});
|
|
192
|
+
});
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import type { EntropyHash } from "#@typeberry/block";
|
|
2
1
|
import type { BytesBlob } from "#@typeberry/bytes";
|
|
3
2
|
import type { ChainSpec } from "#@typeberry/config";
|
|
4
|
-
import {
|
|
5
|
-
import { type U64 } from "#@typeberry/numbers";
|
|
3
|
+
import { PendingTransfer } from "#@typeberry/jam-host-calls";
|
|
6
4
|
import { Operand } from "../accumulate/operand.js";
|
|
7
5
|
export declare enum TransferOperandKind {
|
|
8
6
|
OPERAND = 0,
|
|
@@ -16,40 +14,6 @@ export type TransferOrOperand = {
|
|
|
16
14
|
value: PendingTransfer;
|
|
17
15
|
};
|
|
18
16
|
export declare const TRANSFER_OR_OPERAND: import("@typeberry/codec").Descriptor<TransferOrOperand, TransferOrOperand>;
|
|
19
|
-
declare
|
|
20
|
-
|
|
21
|
-
Refine = 1
|
|
22
|
-
}
|
|
23
|
-
type AccumulateFetchData = {
|
|
24
|
-
context: FetchContext.Accumulate;
|
|
25
|
-
entropy: EntropyHash;
|
|
26
|
-
transfers: PendingTransfer[];
|
|
27
|
-
operands: Operand[];
|
|
28
|
-
};
|
|
29
|
-
type RefineFetchData = {
|
|
30
|
-
context: FetchContext.Refine;
|
|
31
|
-
entropy: undefined;
|
|
32
|
-
};
|
|
33
|
-
export declare class FetchExternalities implements general.IFetchExternalities {
|
|
34
|
-
private fetchData;
|
|
35
|
-
private chainSpec;
|
|
36
|
-
private constructor();
|
|
37
|
-
static createForAccumulate(fetchData: Omit<AccumulateFetchData, "context">, chainSpec: ChainSpec): FetchExternalities;
|
|
38
|
-
static createForRefine(fetchData: Omit<RefineFetchData, "context">, chainSpec: ChainSpec): FetchExternalities;
|
|
39
|
-
constants(): BytesBlob;
|
|
40
|
-
entropy(): BytesBlob | null;
|
|
41
|
-
authorizerTrace(): BytesBlob | null;
|
|
42
|
-
workItemExtrinsic(_workItem: U64 | null, _index: U64): BytesBlob | null;
|
|
43
|
-
workItemImport(_workItem: U64 | null, _index: U64): BytesBlob | null;
|
|
44
|
-
workPackage(): BytesBlob | null;
|
|
45
|
-
authorizer(): BytesBlob | null;
|
|
46
|
-
authorizationToken(): BytesBlob | null;
|
|
47
|
-
refineContext(): BytesBlob | null;
|
|
48
|
-
allWorkItems(): BytesBlob | null;
|
|
49
|
-
oneWorkItem(_workItem: U64): BytesBlob | null;
|
|
50
|
-
workItemPayload(_workItem: U64): BytesBlob | null;
|
|
51
|
-
allTransfersAndOperands(): BytesBlob | null;
|
|
52
|
-
oneTransferOrOperand(index: U64): BytesBlob | null;
|
|
53
|
-
}
|
|
54
|
-
export {};
|
|
17
|
+
export declare const TRANSFERS_AND_OPERANDS: import("@typeberry/codec").Descriptor<TransferOrOperand[], import("@typeberry/codec").SequenceView<TransferOrOperand, TransferOrOperand>>;
|
|
18
|
+
export declare function getEncodedConstants(chainSpec: ChainSpec): BytesBlob;
|
|
55
19
|
//# sourceMappingURL=fetch-externalities.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-externalities.d.ts","sourceRoot":"","sources":["../../../../../../packages/jam/transition/externalities/fetch-externalities.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fetch-externalities.d.ts","sourceRoot":"","sources":["../../../../../../packages/jam/transition/externalities/fetch-externalities.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAS5D,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAInD,oBAAY,mBAAmB;IAC7B,OAAO,IAAI;IACX,QAAQ,IAAI;CACb;AAED,MAAM,MAAM,iBAAiB,GACzB;IACE,IAAI,EAAE,mBAAmB,CAAC,OAAO,CAAC;IAClC,KAAK,EAAE,OAAO,CAAC;CAChB,GACD;IACE,IAAI,EAAE,mBAAmB,CAAC,QAAQ,CAAC;IACnC,KAAK,EAAE,eAAe,CAAC;CACxB,CAAC;AAEN,eAAO,MAAM,mBAAmB,6EAG9B,CAAC;AAEH,eAAO,MAAM,sBAAsB,2IAA4C,CAAC;AA0ChF,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,SAAS,aA6CvD"}
|