@typeberry/lib 0.2.0-74f246e → 0.2.0-8017bfd
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/index.cjs +217 -176
- package/index.d.ts +972 -936
- package/index.js +217 -176
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -10659,7 +10659,6 @@ declare enum UpdatePreimageKind {
|
|
|
10659
10659
|
*/
|
|
10660
10660
|
declare class UpdatePreimage {
|
|
10661
10661
|
private constructor(
|
|
10662
|
-
public readonly serviceId: ServiceId,
|
|
10663
10662
|
public readonly action:
|
|
10664
10663
|
| {
|
|
10665
10664
|
kind: UpdatePreimageKind.Provide;
|
|
@@ -10679,16 +10678,8 @@ declare class UpdatePreimage {
|
|
|
10679
10678
|
) {}
|
|
10680
10679
|
|
|
10681
10680
|
/** A preimage is provided. We should update the lookuphistory and add the preimage to db. */
|
|
10682
|
-
static provide({
|
|
10683
|
-
|
|
10684
|
-
preimage,
|
|
10685
|
-
slot,
|
|
10686
|
-
}: {
|
|
10687
|
-
serviceId: ServiceId;
|
|
10688
|
-
preimage: PreimageItem;
|
|
10689
|
-
slot: TimeSlot | null;
|
|
10690
|
-
}) {
|
|
10691
|
-
return new UpdatePreimage(serviceId, {
|
|
10681
|
+
static provide({ preimage, slot }: { preimage: PreimageItem; slot: TimeSlot | null }) {
|
|
10682
|
+
return new UpdatePreimage({
|
|
10692
10683
|
kind: UpdatePreimageKind.Provide,
|
|
10693
10684
|
preimage,
|
|
10694
10685
|
slot,
|
|
@@ -10696,8 +10687,8 @@ declare class UpdatePreimage {
|
|
|
10696
10687
|
}
|
|
10697
10688
|
|
|
10698
10689
|
/** The preimage should be removed completely from the database. */
|
|
10699
|
-
static remove({
|
|
10700
|
-
return new UpdatePreimage(
|
|
10690
|
+
static remove({ hash, length }: { hash: PreimageHash; length: U32 }) {
|
|
10691
|
+
return new UpdatePreimage({
|
|
10701
10692
|
kind: UpdatePreimageKind.Remove,
|
|
10702
10693
|
hash,
|
|
10703
10694
|
length,
|
|
@@ -10705,8 +10696,8 @@ declare class UpdatePreimage {
|
|
|
10705
10696
|
}
|
|
10706
10697
|
|
|
10707
10698
|
/** Update the lookup history of some preimage or add a new one (request). */
|
|
10708
|
-
static updateOrAdd({
|
|
10709
|
-
return new UpdatePreimage(
|
|
10699
|
+
static updateOrAdd({ lookupHistory }: { lookupHistory: LookupHistoryItem }) {
|
|
10700
|
+
return new UpdatePreimage({
|
|
10710
10701
|
kind: UpdatePreimageKind.UpdateOrAdd,
|
|
10711
10702
|
item: lookupHistory,
|
|
10712
10703
|
});
|
|
@@ -10744,12 +10735,12 @@ declare enum UpdateServiceKind {
|
|
|
10744
10735
|
/** Create a new `Service` instance. */
|
|
10745
10736
|
Create = 1,
|
|
10746
10737
|
}
|
|
10738
|
+
|
|
10747
10739
|
/**
|
|
10748
|
-
* Update service info
|
|
10740
|
+
* Update service info or create a new one.
|
|
10749
10741
|
*/
|
|
10750
10742
|
declare class UpdateService {
|
|
10751
10743
|
private constructor(
|
|
10752
|
-
public readonly serviceId: ServiceId,
|
|
10753
10744
|
public readonly action:
|
|
10754
10745
|
| {
|
|
10755
10746
|
kind: UpdateServiceKind.Update;
|
|
@@ -10762,23 +10753,21 @@ declare class UpdateService {
|
|
|
10762
10753
|
},
|
|
10763
10754
|
) {}
|
|
10764
10755
|
|
|
10765
|
-
static update({
|
|
10766
|
-
return new UpdateService(
|
|
10756
|
+
static update({ serviceInfo }: { serviceInfo: ServiceAccountInfo }) {
|
|
10757
|
+
return new UpdateService({
|
|
10767
10758
|
kind: UpdateServiceKind.Update,
|
|
10768
10759
|
account: serviceInfo,
|
|
10769
10760
|
});
|
|
10770
10761
|
}
|
|
10771
10762
|
|
|
10772
10763
|
static create({
|
|
10773
|
-
serviceId,
|
|
10774
10764
|
serviceInfo,
|
|
10775
10765
|
lookupHistory,
|
|
10776
10766
|
}: {
|
|
10777
|
-
serviceId: ServiceId;
|
|
10778
10767
|
serviceInfo: ServiceAccountInfo;
|
|
10779
10768
|
lookupHistory: LookupHistoryItem | null;
|
|
10780
10769
|
}) {
|
|
10781
|
-
return new UpdateService(
|
|
10770
|
+
return new UpdateService({
|
|
10782
10771
|
kind: UpdateServiceKind.Create,
|
|
10783
10772
|
account: serviceInfo,
|
|
10784
10773
|
lookupHistory,
|
|
@@ -10800,7 +10789,6 @@ declare enum UpdateStorageKind {
|
|
|
10800
10789
|
*/
|
|
10801
10790
|
declare class UpdateStorage {
|
|
10802
10791
|
private constructor(
|
|
10803
|
-
public readonly serviceId: ServiceId,
|
|
10804
10792
|
public readonly action:
|
|
10805
10793
|
| {
|
|
10806
10794
|
kind: UpdateStorageKind.Set;
|
|
@@ -10812,12 +10800,12 @@ declare class UpdateStorage {
|
|
|
10812
10800
|
},
|
|
10813
10801
|
) {}
|
|
10814
10802
|
|
|
10815
|
-
static set({
|
|
10816
|
-
return new UpdateStorage(
|
|
10803
|
+
static set({ storage }: { storage: StorageItem }) {
|
|
10804
|
+
return new UpdateStorage({ kind: UpdateStorageKind.Set, storage });
|
|
10817
10805
|
}
|
|
10818
10806
|
|
|
10819
|
-
static remove({
|
|
10820
|
-
return new UpdateStorage(
|
|
10807
|
+
static remove({ key }: { key: StorageKey }) {
|
|
10808
|
+
return new UpdateStorage({ kind: UpdateStorageKind.Remove, key });
|
|
10821
10809
|
}
|
|
10822
10810
|
|
|
10823
10811
|
get key() {
|
|
@@ -10835,16 +10823,17 @@ declare class UpdateStorage {
|
|
|
10835
10823
|
}
|
|
10836
10824
|
}
|
|
10837
10825
|
|
|
10838
|
-
// TODO [ToDr] This would be more convenient to use if the data was grouped by `ServiceId`.
|
|
10839
10826
|
type ServicesUpdate = {
|
|
10840
10827
|
/** Service ids to remove from state alongside all their data. */
|
|
10841
|
-
|
|
10842
|
-
/** Services
|
|
10843
|
-
|
|
10828
|
+
removed: ServiceId[];
|
|
10829
|
+
/** Services newly created. */
|
|
10830
|
+
created: ServiceId[];
|
|
10831
|
+
/** Services to update. */
|
|
10832
|
+
updated: Map<ServiceId, UpdateService>;
|
|
10844
10833
|
/** Service preimages to update and potentially lookup history */
|
|
10845
|
-
preimages: UpdatePreimage[]
|
|
10834
|
+
preimages: Map<ServiceId, UpdatePreimage[]>;
|
|
10846
10835
|
/** Service storage to update. */
|
|
10847
|
-
storage: UpdateStorage[]
|
|
10836
|
+
storage: Map<ServiceId, UpdateStorage[]>;
|
|
10848
10837
|
};
|
|
10849
10838
|
|
|
10850
10839
|
declare enum UpdateError {
|
|
@@ -11040,13 +11029,13 @@ declare class InMemoryState extends WithDebug implements State, WithStateView, E
|
|
|
11040
11029
|
* Modify the state and apply a single state update.
|
|
11041
11030
|
*/
|
|
11042
11031
|
applyUpdate(update: Partial<State & ServicesUpdate>): Result$2<OK, UpdateError> {
|
|
11043
|
-
const {
|
|
11032
|
+
const { removed, created: _, updated, preimages, storage, ...rest } = update;
|
|
11044
11033
|
// just assign all other variables
|
|
11045
11034
|
Object.assign(this, rest);
|
|
11046
11035
|
|
|
11047
11036
|
// and update the services state
|
|
11048
11037
|
let result: Result<OK, UpdateError>;
|
|
11049
|
-
result = this.updateServices(
|
|
11038
|
+
result = this.updateServices(updated);
|
|
11050
11039
|
if (result.isError) {
|
|
11051
11040
|
return result;
|
|
11052
11041
|
}
|
|
@@ -11058,7 +11047,7 @@ declare class InMemoryState extends WithDebug implements State, WithStateView, E
|
|
|
11058
11047
|
if (result.isError) {
|
|
11059
11048
|
return result;
|
|
11060
11049
|
}
|
|
11061
|
-
this.removeServices(
|
|
11050
|
+
this.removeServices(removed);
|
|
11062
11051
|
|
|
11063
11052
|
return Result.ok(OK);
|
|
11064
11053
|
}
|
|
@@ -11070,37 +11059,44 @@ declare class InMemoryState extends WithDebug implements State, WithStateView, E
|
|
|
11070
11059
|
}
|
|
11071
11060
|
}
|
|
11072
11061
|
|
|
11073
|
-
private updateStorage(
|
|
11074
|
-
|
|
11075
|
-
|
|
11076
|
-
|
|
11077
|
-
|
|
11078
|
-
|
|
11079
|
-
|
|
11080
|
-
|
|
11081
|
-
)
|
|
11082
|
-
|
|
11062
|
+
private updateStorage(storageUpdates: Map<ServiceId, UpdateStorage[]> | undefined): Result$2<OK, UpdateError> {
|
|
11063
|
+
if (storageUpdates === undefined) {
|
|
11064
|
+
return Result.ok(OK);
|
|
11065
|
+
}
|
|
11066
|
+
for (const [serviceId, updates] of storageUpdates.entries()) {
|
|
11067
|
+
for (const update of updates) {
|
|
11068
|
+
const { kind } = update.action;
|
|
11069
|
+
const service = this.services.get(serviceId);
|
|
11070
|
+
if (service === undefined) {
|
|
11071
|
+
return Result.error(
|
|
11072
|
+
UpdateError.NoService,
|
|
11073
|
+
`Attempting to update storage of non-existing service: ${serviceId}`,
|
|
11074
|
+
);
|
|
11075
|
+
}
|
|
11083
11076
|
|
|
11084
|
-
|
|
11085
|
-
|
|
11086
|
-
|
|
11087
|
-
|
|
11088
|
-
|
|
11089
|
-
|
|
11077
|
+
if (kind === UpdateStorageKind.Set) {
|
|
11078
|
+
const { key, value } = update.action.storage;
|
|
11079
|
+
service.data.storage.set(key.toString(), StorageItem.create({ key, value }));
|
|
11080
|
+
} else if (kind === UpdateStorageKind.Remove) {
|
|
11081
|
+
const { key } = update.action;
|
|
11082
|
+
check`
|
|
11090
11083
|
${service.data.storage.has(key.toString())}
|
|
11091
|
-
Attempting to remove non-existing storage item at ${serviceId}: ${action.key}
|
|
11084
|
+
Attempting to remove non-existing storage item at ${serviceId}: ${update.action.key}
|
|
11092
11085
|
`;
|
|
11093
|
-
|
|
11094
|
-
|
|
11095
|
-
|
|
11086
|
+
service.data.storage.delete(key.toString());
|
|
11087
|
+
} else {
|
|
11088
|
+
assertNever(kind);
|
|
11089
|
+
}
|
|
11096
11090
|
}
|
|
11097
11091
|
}
|
|
11098
|
-
|
|
11099
11092
|
return Result.ok(OK);
|
|
11100
11093
|
}
|
|
11101
11094
|
|
|
11102
|
-
private updatePreimages(
|
|
11103
|
-
|
|
11095
|
+
private updatePreimages(preimagesUpdates: Map<ServiceId, UpdatePreimage[]> | undefined): Result$2<OK, UpdateError> {
|
|
11096
|
+
if (preimagesUpdates === undefined) {
|
|
11097
|
+
return Result.ok(OK);
|
|
11098
|
+
}
|
|
11099
|
+
for (const [serviceId, updates] of preimagesUpdates.entries()) {
|
|
11104
11100
|
const service = this.services.get(serviceId);
|
|
11105
11101
|
if (service === undefined) {
|
|
11106
11102
|
return Result.error(
|
|
@@ -11108,53 +11104,61 @@ declare class InMemoryState extends WithDebug implements State, WithStateView, E
|
|
|
11108
11104
|
`Attempting to update preimage of non-existing service: ${serviceId}`,
|
|
11109
11105
|
);
|
|
11110
11106
|
}
|
|
11111
|
-
const
|
|
11112
|
-
|
|
11113
|
-
|
|
11114
|
-
|
|
11115
|
-
|
|
11116
|
-
|
|
11117
|
-
|
|
11118
|
-
|
|
11119
|
-
|
|
11120
|
-
const length = tryAsU32(preimage.blob.length);
|
|
11121
|
-
const lookup = new LookupHistoryItem(preimage.hash, length, tryAsLookupHistorySlots([slot]));
|
|
11122
|
-
if (lookupHistory === undefined) {
|
|
11123
|
-
// no lookup history for that preimage at all (edge case, should be requested)
|
|
11124
|
-
service.data.lookupHistory.set(preimage.hash, [lookup]);
|
|
11125
|
-
} else {
|
|
11126
|
-
// insert or replace exiting entry
|
|
11127
|
-
const index = lookupHistory.map((x) => x.length).indexOf(length);
|
|
11128
|
-
lookupHistory.splice(index, index === -1 ? 0 : 1, lookup);
|
|
11107
|
+
for (const update of updates) {
|
|
11108
|
+
const { kind } = update.action;
|
|
11109
|
+
if (kind === UpdatePreimageKind.Provide) {
|
|
11110
|
+
const { preimage, slot } = update.action;
|
|
11111
|
+
if (service.data.preimages.has(preimage.hash)) {
|
|
11112
|
+
return Result.error(
|
|
11113
|
+
UpdateError.PreimageExists,
|
|
11114
|
+
`Overwriting existing preimage at ${serviceId}: ${preimage}`,
|
|
11115
|
+
);
|
|
11129
11116
|
}
|
|
11117
|
+
service.data.preimages.set(preimage.hash, preimage);
|
|
11118
|
+
if (slot !== null) {
|
|
11119
|
+
const lookupHistory = service.data.lookupHistory.get(preimage.hash);
|
|
11120
|
+
const length = tryAsU32(preimage.blob.length);
|
|
11121
|
+
const lookup = new LookupHistoryItem(preimage.hash, length, tryAsLookupHistorySlots([slot]));
|
|
11122
|
+
if (lookupHistory === undefined) {
|
|
11123
|
+
// no lookup history for that preimage at all (edge case, should be requested)
|
|
11124
|
+
service.data.lookupHistory.set(preimage.hash, [lookup]);
|
|
11125
|
+
} else {
|
|
11126
|
+
// insert or replace exiting entry
|
|
11127
|
+
const index = lookupHistory.map((x) => x.length).indexOf(length);
|
|
11128
|
+
lookupHistory.splice(index, index === -1 ? 0 : 1, lookup);
|
|
11129
|
+
}
|
|
11130
|
+
}
|
|
11131
|
+
} else if (kind === UpdatePreimageKind.Remove) {
|
|
11132
|
+
const { hash, length } = update.action;
|
|
11133
|
+
service.data.preimages.delete(hash);
|
|
11134
|
+
const history = service.data.lookupHistory.get(hash) ?? [];
|
|
11135
|
+
const idx = history.map((x) => x.length).indexOf(length);
|
|
11136
|
+
if (idx !== -1) {
|
|
11137
|
+
history.splice(idx, 1);
|
|
11138
|
+
}
|
|
11139
|
+
} else if (kind === UpdatePreimageKind.UpdateOrAdd) {
|
|
11140
|
+
const { item } = update.action;
|
|
11141
|
+
const history = service.data.lookupHistory.get(item.hash) ?? [];
|
|
11142
|
+
const existingIdx = history.map((x) => x.length).indexOf(item.length);
|
|
11143
|
+
const removeCount = existingIdx === -1 ? 0 : 1;
|
|
11144
|
+
history.splice(existingIdx, removeCount, item);
|
|
11145
|
+
service.data.lookupHistory.set(item.hash, history);
|
|
11146
|
+
} else {
|
|
11147
|
+
assertNever(kind);
|
|
11130
11148
|
}
|
|
11131
|
-
} else if (kind === UpdatePreimageKind.Remove) {
|
|
11132
|
-
const { hash, length } = action;
|
|
11133
|
-
service.data.preimages.delete(hash);
|
|
11134
|
-
const history = service.data.lookupHistory.get(hash) ?? [];
|
|
11135
|
-
const idx = history.map((x) => x.length).indexOf(length);
|
|
11136
|
-
if (idx !== -1) {
|
|
11137
|
-
history.splice(idx, 1);
|
|
11138
|
-
}
|
|
11139
|
-
} else if (kind === UpdatePreimageKind.UpdateOrAdd) {
|
|
11140
|
-
const { item } = action;
|
|
11141
|
-
const history = service.data.lookupHistory.get(item.hash) ?? [];
|
|
11142
|
-
const existingIdx = history.map((x) => x.length).indexOf(item.length);
|
|
11143
|
-
const removeCount = existingIdx === -1 ? 0 : 1;
|
|
11144
|
-
history.splice(existingIdx, removeCount, item);
|
|
11145
|
-
service.data.lookupHistory.set(item.hash, history);
|
|
11146
|
-
} else {
|
|
11147
|
-
assertNever(kind);
|
|
11148
11149
|
}
|
|
11149
11150
|
}
|
|
11150
11151
|
return Result.ok(OK);
|
|
11151
11152
|
}
|
|
11152
11153
|
|
|
11153
|
-
private updateServices(servicesUpdates
|
|
11154
|
-
|
|
11155
|
-
|
|
11154
|
+
private updateServices(servicesUpdates: Map<ServiceId, UpdateService> | undefined): Result$2<OK, UpdateError> {
|
|
11155
|
+
if (servicesUpdates === undefined) {
|
|
11156
|
+
return Result.ok(OK);
|
|
11157
|
+
}
|
|
11158
|
+
for (const [serviceId, update] of servicesUpdates.entries()) {
|
|
11159
|
+
const { kind, account } = update.action;
|
|
11156
11160
|
if (kind === UpdateServiceKind.Create) {
|
|
11157
|
-
const { lookupHistory } = action;
|
|
11161
|
+
const { lookupHistory } = update.action;
|
|
11158
11162
|
if (this.services.has(serviceId)) {
|
|
11159
11163
|
return Result.error(UpdateError.DuplicateService, `${serviceId} already exists!`);
|
|
11160
11164
|
}
|
|
@@ -11975,89 +11979,104 @@ declare function* serializeStateUpdate(
|
|
|
11975
11979
|
const encode = <T>(codec: Encode<T>, val: T) => Encoder.encodeObject(codec, val, spec);
|
|
11976
11980
|
|
|
11977
11981
|
// then let's proceed with service updates
|
|
11978
|
-
yield* serializeServiceUpdates(update.
|
|
11982
|
+
yield* serializeServiceUpdates(update.updated, encode, blake2b);
|
|
11979
11983
|
yield* serializePreimages(update.preimages, encode, blake2b);
|
|
11980
11984
|
yield* serializeStorage(update.storage, blake2b);
|
|
11981
|
-
yield* serializeRemovedServices(update.
|
|
11985
|
+
yield* serializeRemovedServices(update.removed);
|
|
11982
11986
|
}
|
|
11983
11987
|
|
|
11984
11988
|
declare function* serializeRemovedServices(servicesRemoved: ServiceId[] | undefined): Generator<StateEntryUpdate> {
|
|
11985
|
-
|
|
11989
|
+
if (servicesRemoved === undefined) {
|
|
11990
|
+
return;
|
|
11991
|
+
}
|
|
11992
|
+
for (const serviceId of servicesRemoved) {
|
|
11986
11993
|
// TODO [ToDr] what about all data associated with a service?
|
|
11987
11994
|
const codec = serialize.serviceData(serviceId);
|
|
11988
11995
|
yield [StateEntryUpdateAction.Remove, codec.key, EMPTY_BLOB];
|
|
11989
11996
|
}
|
|
11990
11997
|
}
|
|
11991
11998
|
|
|
11992
|
-
declare function* serializeStorage(
|
|
11993
|
-
|
|
11994
|
-
|
|
11995
|
-
|
|
11996
|
-
|
|
11997
|
-
|
|
11998
|
-
|
|
11999
|
-
|
|
12000
|
-
|
|
12001
|
-
|
|
12002
|
-
|
|
12003
|
-
|
|
12004
|
-
|
|
12005
|
-
|
|
11999
|
+
declare function* serializeStorage(
|
|
12000
|
+
storageUpdates: Map<ServiceId, UpdateStorage[]> | undefined,
|
|
12001
|
+
blake2b: Blake2b,
|
|
12002
|
+
): Generator<StateEntryUpdate> {
|
|
12003
|
+
if (storageUpdates === undefined) {
|
|
12004
|
+
return;
|
|
12005
|
+
}
|
|
12006
|
+
for (const [serviceId, updates] of storageUpdates.entries()) {
|
|
12007
|
+
for (const { action } of updates) {
|
|
12008
|
+
switch (action.kind) {
|
|
12009
|
+
case UpdateStorageKind.Set: {
|
|
12010
|
+
const key = action.storage.key;
|
|
12011
|
+
const codec = serialize.serviceStorage(blake2b, serviceId, key);
|
|
12012
|
+
yield [StateEntryUpdateAction.Insert, codec.key, action.storage.value];
|
|
12013
|
+
break;
|
|
12014
|
+
}
|
|
12015
|
+
case UpdateStorageKind.Remove: {
|
|
12016
|
+
const key = action.key;
|
|
12017
|
+
const codec = serialize.serviceStorage(blake2b, serviceId, key);
|
|
12018
|
+
yield [StateEntryUpdateAction.Remove, codec.key, EMPTY_BLOB];
|
|
12019
|
+
break;
|
|
12020
|
+
}
|
|
12006
12021
|
}
|
|
12007
|
-
default:
|
|
12008
|
-
assertNever(action);
|
|
12009
12022
|
}
|
|
12010
12023
|
}
|
|
12011
12024
|
}
|
|
12012
12025
|
|
|
12013
12026
|
declare function* serializePreimages(
|
|
12014
|
-
|
|
12027
|
+
preimagesUpdates: Map<ServiceId, UpdatePreimage[]> | undefined,
|
|
12015
12028
|
encode: EncodeFun,
|
|
12016
12029
|
blake2b: Blake2b,
|
|
12017
12030
|
): Generator<StateEntryUpdate> {
|
|
12018
|
-
|
|
12019
|
-
|
|
12020
|
-
|
|
12021
|
-
|
|
12022
|
-
|
|
12023
|
-
|
|
12024
|
-
|
|
12025
|
-
|
|
12026
|
-
const
|
|
12027
|
-
yield [
|
|
12028
|
-
|
|
12029
|
-
|
|
12030
|
-
|
|
12031
|
-
|
|
12031
|
+
if (preimagesUpdates === undefined) {
|
|
12032
|
+
return;
|
|
12033
|
+
}
|
|
12034
|
+
for (const [serviceId, updates] of preimagesUpdates.entries()) {
|
|
12035
|
+
for (const { action } of updates) {
|
|
12036
|
+
switch (action.kind) {
|
|
12037
|
+
case UpdatePreimageKind.Provide: {
|
|
12038
|
+
const { hash, blob } = action.preimage;
|
|
12039
|
+
const codec = serialize.servicePreimages(blake2b, serviceId, hash);
|
|
12040
|
+
yield [StateEntryUpdateAction.Insert, codec.key, blob];
|
|
12041
|
+
|
|
12042
|
+
if (action.slot !== null) {
|
|
12043
|
+
const codec2 = serialize.serviceLookupHistory(blake2b, serviceId, hash, tryAsU32(blob.length));
|
|
12044
|
+
yield [
|
|
12045
|
+
StateEntryUpdateAction.Insert,
|
|
12046
|
+
codec2.key,
|
|
12047
|
+
encode(codec2.Codec, tryAsLookupHistorySlots([action.slot])),
|
|
12048
|
+
];
|
|
12049
|
+
}
|
|
12050
|
+
break;
|
|
12032
12051
|
}
|
|
12033
|
-
|
|
12034
|
-
|
|
12035
|
-
|
|
12036
|
-
|
|
12037
|
-
|
|
12038
|
-
|
|
12039
|
-
|
|
12040
|
-
|
|
12041
|
-
|
|
12042
|
-
|
|
12043
|
-
const codec = serialize.servicePreimages(blake2b, serviceId, hash);
|
|
12044
|
-
yield [StateEntryUpdateAction.Remove, codec.key, EMPTY_BLOB];
|
|
12052
|
+
case UpdatePreimageKind.UpdateOrAdd: {
|
|
12053
|
+
const { hash, length, slots } = action.item;
|
|
12054
|
+
const codec = serialize.serviceLookupHistory(blake2b, serviceId, hash, length);
|
|
12055
|
+
yield [StateEntryUpdateAction.Insert, codec.key, encode(codec.Codec, slots)];
|
|
12056
|
+
break;
|
|
12057
|
+
}
|
|
12058
|
+
case UpdatePreimageKind.Remove: {
|
|
12059
|
+
const { hash, length } = action;
|
|
12060
|
+
const codec = serialize.servicePreimages(blake2b, serviceId, hash);
|
|
12061
|
+
yield [StateEntryUpdateAction.Remove, codec.key, EMPTY_BLOB];
|
|
12045
12062
|
|
|
12046
|
-
|
|
12047
|
-
|
|
12048
|
-
|
|
12063
|
+
const codec2 = serialize.serviceLookupHistory(blake2b, serviceId, hash, length);
|
|
12064
|
+
yield [StateEntryUpdateAction.Remove, codec2.key, EMPTY_BLOB];
|
|
12065
|
+
break;
|
|
12066
|
+
}
|
|
12049
12067
|
}
|
|
12050
|
-
default:
|
|
12051
|
-
assertNever(action);
|
|
12052
12068
|
}
|
|
12053
12069
|
}
|
|
12054
12070
|
}
|
|
12055
12071
|
declare function* serializeServiceUpdates(
|
|
12056
|
-
servicesUpdates: UpdateService
|
|
12072
|
+
servicesUpdates: Map<ServiceId, UpdateService> | undefined,
|
|
12057
12073
|
encode: EncodeFun,
|
|
12058
12074
|
blake2b: Blake2b,
|
|
12059
12075
|
): Generator<StateEntryUpdate> {
|
|
12060
|
-
|
|
12076
|
+
if (servicesUpdates === undefined) {
|
|
12077
|
+
return;
|
|
12078
|
+
}
|
|
12079
|
+
for (const [serviceId, { action }] of servicesUpdates.entries()) {
|
|
12061
12080
|
// new service being created or updated
|
|
12062
12081
|
const codec = serialize.serviceData(serviceId);
|
|
12063
12082
|
yield [StateEntryUpdateAction.Insert, codec.key, encode(codec.Codec, action.account)];
|
|
@@ -14196,6 +14215,82 @@ interface GasCounter {
|
|
|
14196
14215
|
sub(g: Gas): boolean;
|
|
14197
14216
|
}
|
|
14198
14217
|
|
|
14218
|
+
declare const NO_OF_REGISTERS$1 = 13;
|
|
14219
|
+
|
|
14220
|
+
type RegisterIndex = Opaque<number, "register index">;
|
|
14221
|
+
|
|
14222
|
+
declare class Registers {
|
|
14223
|
+
private asSigned: BigInt64Array;
|
|
14224
|
+
private asUnsigned: BigUint64Array;
|
|
14225
|
+
|
|
14226
|
+
constructor(private readonly bytes = safeAllocUint8Array(NO_OF_REGISTERS << REGISTER_SIZE_SHIFT)) {
|
|
14227
|
+
check`${bytes.length === NO_OF_REGISTERS << REGISTER_SIZE_SHIFT} Invalid size of registers array.`;
|
|
14228
|
+
this.asSigned = new BigInt64Array(bytes.buffer, bytes.byteOffset);
|
|
14229
|
+
this.asUnsigned = new BigUint64Array(bytes.buffer, bytes.byteOffset);
|
|
14230
|
+
}
|
|
14231
|
+
|
|
14232
|
+
static fromBytes(bytes: Uint8Array) {
|
|
14233
|
+
check`${bytes.length === NO_OF_REGISTERS << REGISTER_SIZE_SHIFT} Invalid size of registers array.`;
|
|
14234
|
+
return new Registers(bytes);
|
|
14235
|
+
}
|
|
14236
|
+
|
|
14237
|
+
getBytesAsLittleEndian(index: number, len: number) {
|
|
14238
|
+
const offset = index << REGISTER_SIZE_SHIFT;
|
|
14239
|
+
return this.bytes.subarray(offset, offset + len);
|
|
14240
|
+
}
|
|
14241
|
+
|
|
14242
|
+
getAllBytesAsLittleEndian() {
|
|
14243
|
+
return this.bytes;
|
|
14244
|
+
}
|
|
14245
|
+
|
|
14246
|
+
copyFrom(regs: Registers | BigUint64Array) {
|
|
14247
|
+
const array = regs instanceof BigUint64Array ? regs : regs.asUnsigned;
|
|
14248
|
+
this.asUnsigned.set(array);
|
|
14249
|
+
}
|
|
14250
|
+
|
|
14251
|
+
reset() {
|
|
14252
|
+
for (let i = 0; i < NO_OF_REGISTERS; i++) {
|
|
14253
|
+
this.asUnsigned[i] = 0n;
|
|
14254
|
+
}
|
|
14255
|
+
}
|
|
14256
|
+
|
|
14257
|
+
getLowerU32(registerIndex: number) {
|
|
14258
|
+
return Number(this.asUnsigned[registerIndex] & 0xff_ff_ff_ffn);
|
|
14259
|
+
}
|
|
14260
|
+
|
|
14261
|
+
getLowerI32(registerIndex: number) {
|
|
14262
|
+
return Number(this.getLowerU32(registerIndex)) >> 0;
|
|
14263
|
+
}
|
|
14264
|
+
|
|
14265
|
+
setU32(registerIndex: number, value: number) {
|
|
14266
|
+
this.asUnsigned[registerIndex] = signExtend32To64(value);
|
|
14267
|
+
}
|
|
14268
|
+
|
|
14269
|
+
setI32(registerIndex: number, value: number) {
|
|
14270
|
+
this.asSigned[registerIndex] = signExtend32To64(value);
|
|
14271
|
+
}
|
|
14272
|
+
|
|
14273
|
+
getU64(registerIndex: number) {
|
|
14274
|
+
return this.asUnsigned[registerIndex];
|
|
14275
|
+
}
|
|
14276
|
+
|
|
14277
|
+
getI64(registerIndex: number) {
|
|
14278
|
+
return this.asSigned[registerIndex];
|
|
14279
|
+
}
|
|
14280
|
+
|
|
14281
|
+
setU64(registerIndex: number, value: bigint) {
|
|
14282
|
+
this.asUnsigned[registerIndex] = value;
|
|
14283
|
+
}
|
|
14284
|
+
|
|
14285
|
+
setI64(registerIndex: number, value: bigint) {
|
|
14286
|
+
this.asSigned[registerIndex] = value;
|
|
14287
|
+
}
|
|
14288
|
+
|
|
14289
|
+
getAllU64() {
|
|
14290
|
+
return this.asUnsigned;
|
|
14291
|
+
}
|
|
14292
|
+
}
|
|
14293
|
+
|
|
14199
14294
|
/**
|
|
14200
14295
|
* Mask class is an implementation of skip function defined in GP.
|
|
14201
14296
|
*
|
|
@@ -14365,82 +14460,6 @@ declare class ImmediateDecoder {
|
|
|
14365
14460
|
}
|
|
14366
14461
|
}
|
|
14367
14462
|
|
|
14368
|
-
declare const NO_OF_REGISTERS$1 = 13;
|
|
14369
|
-
|
|
14370
|
-
type RegisterIndex = Opaque<number, "register index">;
|
|
14371
|
-
|
|
14372
|
-
declare class Registers {
|
|
14373
|
-
private asSigned: BigInt64Array;
|
|
14374
|
-
private asUnsigned: BigUint64Array;
|
|
14375
|
-
|
|
14376
|
-
constructor(private readonly bytes = safeAllocUint8Array(NO_OF_REGISTERS << REGISTER_SIZE_SHIFT)) {
|
|
14377
|
-
check`${bytes.length === NO_OF_REGISTERS << REGISTER_SIZE_SHIFT} Invalid size of registers array.`;
|
|
14378
|
-
this.asSigned = new BigInt64Array(bytes.buffer, bytes.byteOffset);
|
|
14379
|
-
this.asUnsigned = new BigUint64Array(bytes.buffer, bytes.byteOffset);
|
|
14380
|
-
}
|
|
14381
|
-
|
|
14382
|
-
static fromBytes(bytes: Uint8Array) {
|
|
14383
|
-
check`${bytes.length === NO_OF_REGISTERS << REGISTER_SIZE_SHIFT} Invalid size of registers array.`;
|
|
14384
|
-
return new Registers(bytes);
|
|
14385
|
-
}
|
|
14386
|
-
|
|
14387
|
-
getBytesAsLittleEndian(index: number, len: number) {
|
|
14388
|
-
const offset = index << REGISTER_SIZE_SHIFT;
|
|
14389
|
-
return this.bytes.subarray(offset, offset + len);
|
|
14390
|
-
}
|
|
14391
|
-
|
|
14392
|
-
getAllBytesAsLittleEndian() {
|
|
14393
|
-
return this.bytes;
|
|
14394
|
-
}
|
|
14395
|
-
|
|
14396
|
-
copyFrom(regs: Registers | BigUint64Array) {
|
|
14397
|
-
const array = regs instanceof BigUint64Array ? regs : regs.asUnsigned;
|
|
14398
|
-
this.asUnsigned.set(array);
|
|
14399
|
-
}
|
|
14400
|
-
|
|
14401
|
-
reset() {
|
|
14402
|
-
for (let i = 0; i < NO_OF_REGISTERS; i++) {
|
|
14403
|
-
this.asUnsigned[i] = 0n;
|
|
14404
|
-
}
|
|
14405
|
-
}
|
|
14406
|
-
|
|
14407
|
-
getLowerU32(registerIndex: number) {
|
|
14408
|
-
return Number(this.asUnsigned[registerIndex] & 0xff_ff_ff_ffn);
|
|
14409
|
-
}
|
|
14410
|
-
|
|
14411
|
-
getLowerI32(registerIndex: number) {
|
|
14412
|
-
return Number(this.getLowerU32(registerIndex)) >> 0;
|
|
14413
|
-
}
|
|
14414
|
-
|
|
14415
|
-
setU32(registerIndex: number, value: number) {
|
|
14416
|
-
this.asUnsigned[registerIndex] = signExtend32To64(value);
|
|
14417
|
-
}
|
|
14418
|
-
|
|
14419
|
-
setI32(registerIndex: number, value: number) {
|
|
14420
|
-
this.asSigned[registerIndex] = signExtend32To64(value);
|
|
14421
|
-
}
|
|
14422
|
-
|
|
14423
|
-
getU64(registerIndex: number) {
|
|
14424
|
-
return this.asUnsigned[registerIndex];
|
|
14425
|
-
}
|
|
14426
|
-
|
|
14427
|
-
getI64(registerIndex: number) {
|
|
14428
|
-
return this.asSigned[registerIndex];
|
|
14429
|
-
}
|
|
14430
|
-
|
|
14431
|
-
setU64(registerIndex: number, value: bigint) {
|
|
14432
|
-
this.asUnsigned[registerIndex] = value;
|
|
14433
|
-
}
|
|
14434
|
-
|
|
14435
|
-
setI64(registerIndex: number, value: bigint) {
|
|
14436
|
-
this.asSigned[registerIndex] = value;
|
|
14437
|
-
}
|
|
14438
|
-
|
|
14439
|
-
getAllU64() {
|
|
14440
|
-
return this.asUnsigned;
|
|
14441
|
-
}
|
|
14442
|
-
}
|
|
14443
|
-
|
|
14444
14463
|
declare class NibblesDecoder {
|
|
14445
14464
|
private byte = new Int8Array(1);
|
|
14446
14465
|
|
|
@@ -17877,870 +17896,884 @@ declare namespace index$8 {
|
|
|
17877
17896
|
export type { index$8_BigGas as BigGas, index$8_Gas as Gas, index$8_GasCounter as GasCounter, index$8_InterpreterOptions as InterpreterOptions, index$8_MemoryIndex as MemoryIndex, index$8_SbrkIndex as SbrkIndex, index$8_SmallGas as SmallGas };
|
|
17878
17897
|
}
|
|
17879
17898
|
|
|
17880
|
-
|
|
17881
|
-
|
|
17882
|
-
|
|
17883
|
-
* https://graypaper.fluffylabs.dev/#/1c979cb/2e3f012e3f01?v=0.7.1
|
|
17884
|
-
*/
|
|
17885
|
-
type ProgramCounter = Opaque<U64, "ProgramCounter[u64]">;
|
|
17886
|
-
/** Convert a number into ProgramCounter. */
|
|
17887
|
-
declare const tryAsProgramCounter = (v: number | bigint): ProgramCounter => asOpaqueType(tryAsU64(v));
|
|
17888
|
-
|
|
17889
|
-
/** Running PVM instance identifier. */
|
|
17890
|
-
type MachineId = Opaque<U64, "MachineId[u64]">;
|
|
17891
|
-
/** Convert a number into PVM instance identifier. */
|
|
17892
|
-
declare const tryAsMachineId = (v: number | bigint): MachineId => asOpaqueType(tryAsU64(v));
|
|
17893
|
-
|
|
17894
|
-
declare class MachineInstance {
|
|
17895
|
-
async run(gas: BigGas, registers: Registers): Promise<MachineResult> {
|
|
17896
|
-
return {
|
|
17897
|
-
result: {
|
|
17898
|
-
status: Status.OK,
|
|
17899
|
-
},
|
|
17900
|
-
gas,
|
|
17901
|
-
registers,
|
|
17902
|
-
};
|
|
17903
|
-
}
|
|
17899
|
+
interface IHostCallMemory {
|
|
17900
|
+
storeFrom(address: U64, bytes: Uint8Array): Result$2<OK, PageFault | OutOfBounds>;
|
|
17901
|
+
loadInto(result: Uint8Array, startAddress: U64): Result$2<OK, PageFault | OutOfBounds>;
|
|
17904
17902
|
}
|
|
17905
17903
|
|
|
17906
|
-
|
|
17907
|
-
|
|
17908
|
-
|
|
17909
|
-
|
|
17910
|
-
|
|
17911
|
-
|
|
17912
|
-
status: typeof Status.FAULT;
|
|
17913
|
-
address: U64;
|
|
17904
|
+
declare class HostCallMemory implements IHostCallMemory {
|
|
17905
|
+
constructor(private readonly memory: Memory) {}
|
|
17906
|
+
|
|
17907
|
+
storeFrom(address: U64, bytes: Uint8Array): Result$2<OK, PageFault | OutOfBounds> {
|
|
17908
|
+
if (bytes.length === 0) {
|
|
17909
|
+
return Result.ok(OK);
|
|
17914
17910
|
}
|
|
17915
|
-
| {
|
|
17916
|
-
status: typeof Status.OK | typeof Status.HALT | typeof Status.PANIC | typeof Status.OOG;
|
|
17917
|
-
};
|
|
17918
17911
|
|
|
17919
|
-
|
|
17920
|
-
|
|
17921
|
-
|
|
17922
|
-
gas: BigGas;
|
|
17923
|
-
registers: Registers;
|
|
17924
|
-
};
|
|
17912
|
+
if (address + tryAsU64(bytes.length) > MEMORY_SIZE) {
|
|
17913
|
+
return Result.error(new OutOfBounds());
|
|
17914
|
+
}
|
|
17925
17915
|
|
|
17926
|
-
|
|
17927
|
-
|
|
17928
|
-
/** Zeroes memory and set access to unreadable. */
|
|
17929
|
-
Void = 0,
|
|
17930
|
-
/** Zeroes memory and set access to read-only. */
|
|
17931
|
-
ZeroRead = 1,
|
|
17932
|
-
/** Zeroes memory and set access to read-write. */
|
|
17933
|
-
ZeroWrite = 2,
|
|
17934
|
-
/** Preserve memory and set access to read-only. */
|
|
17935
|
-
Read = 3,
|
|
17936
|
-
/** Preserve memory and set access to read-write. */
|
|
17937
|
-
Write = 4,
|
|
17938
|
-
}
|
|
17916
|
+
return this.memory.storeFrom(tryAsMemoryIndex(Number(address)), bytes);
|
|
17917
|
+
}
|
|
17939
17918
|
|
|
17940
|
-
|
|
17941
|
-
|
|
17942
|
-
|
|
17919
|
+
loadInto(result: Uint8Array, startAddress: U64): Result$2<OK, PageFault | OutOfBounds> {
|
|
17920
|
+
if (result.length === 0) {
|
|
17921
|
+
return Result.ok(OK);
|
|
17922
|
+
}
|
|
17943
17923
|
|
|
17944
|
-
|
|
17945
|
-
|
|
17946
|
-
|
|
17947
|
-
SourcePageFault = 0,
|
|
17948
|
-
/** Destination page fault. */
|
|
17949
|
-
DestinationPageFault = 1,
|
|
17950
|
-
/** No machine under given machine index. */
|
|
17951
|
-
NoMachine = 2,
|
|
17952
|
-
}
|
|
17924
|
+
if (startAddress + tryAsU64(result.length) > MEMORY_SIZE) {
|
|
17925
|
+
return Result.error(new OutOfBounds());
|
|
17926
|
+
}
|
|
17953
17927
|
|
|
17954
|
-
|
|
17955
|
-
|
|
17956
|
-
NoMachine = 0,
|
|
17957
|
-
/** Attempting to void or zero non-accessible page. */
|
|
17958
|
-
InvalidPage = 1,
|
|
17928
|
+
return this.memory.loadInto(result, tryAsMemoryIndex(Number(startAddress)));
|
|
17929
|
+
}
|
|
17959
17930
|
}
|
|
17960
17931
|
|
|
17961
|
-
|
|
17962
|
-
|
|
17963
|
-
|
|
17964
|
-
/** Invalid memory operation. */
|
|
17965
|
-
InvalidOperation = 1,
|
|
17966
|
-
/** Attempting to change non-accessible page or trying to preserve value of voided page. */
|
|
17967
|
-
InvalidPage = 2,
|
|
17932
|
+
interface IHostCallRegisters {
|
|
17933
|
+
get(registerIndex: number): U64;
|
|
17934
|
+
set(registerIndex: number, value: U64): void;
|
|
17968
17935
|
}
|
|
17969
17936
|
|
|
17970
|
-
|
|
17971
|
-
|
|
17972
|
-
type NoMachineError = typeof NoMachineError;
|
|
17973
|
-
|
|
17974
|
-
/** Too many segments already exported. */
|
|
17975
|
-
declare const SegmentExportError = Symbol("Too many segments already exported.");
|
|
17976
|
-
type SegmentExportError = typeof SegmentExportError;
|
|
17977
|
-
|
|
17978
|
-
/** Host functions external invocations available during refine phase. */
|
|
17979
|
-
interface RefineExternalities {
|
|
17980
|
-
/** Forget a previously started nested VM. */
|
|
17981
|
-
machineExpunge(machineIndex: MachineId): Promise<Result$2<ProgramCounter, NoMachineError>>;
|
|
17937
|
+
declare class HostCallRegisters implements IHostCallRegisters {
|
|
17938
|
+
constructor(private readonly registers: Registers) {}
|
|
17982
17939
|
|
|
17983
|
-
|
|
17984
|
-
|
|
17940
|
+
get(registerIndex: number): U64 {
|
|
17941
|
+
return tryAsU64(this.registers.getU64(registerIndex));
|
|
17942
|
+
}
|
|
17985
17943
|
|
|
17986
|
-
|
|
17987
|
-
|
|
17944
|
+
set(registerIndex: number, value: U64) {
|
|
17945
|
+
this.registers.setU64(registerIndex, value);
|
|
17946
|
+
}
|
|
17947
|
+
}
|
|
17988
17948
|
|
|
17989
|
-
|
|
17990
|
-
|
|
17991
|
-
|
|
17992
|
-
|
|
17993
|
-
sourceStart: U64,
|
|
17994
|
-
length: U64,
|
|
17995
|
-
destination: Memory,
|
|
17996
|
-
): Promise<Result$2<OK, PeekPokeError>>;
|
|
17949
|
+
/** Strictly-typed host call index. */
|
|
17950
|
+
type HostCallIndex = Opaque<U32, "HostCallIndex[U32]">;
|
|
17951
|
+
/** Attempt to convert a number into `HostCallIndex`. */
|
|
17952
|
+
declare const tryAsHostCallIndex = (v: number): HostCallIndex => asOpaqueType(tryAsU32(v));
|
|
17997
17953
|
|
|
17998
|
-
|
|
17999
|
-
|
|
18000
|
-
|
|
18001
|
-
|
|
18002
|
-
|
|
18003
|
-
|
|
18004
|
-
|
|
18005
|
-
|
|
17954
|
+
/**
|
|
17955
|
+
* Host-call exit reason.
|
|
17956
|
+
*
|
|
17957
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/24a30124a501?v=0.7.2
|
|
17958
|
+
*/
|
|
17959
|
+
declare enum PvmExecution {
|
|
17960
|
+
Halt = 0,
|
|
17961
|
+
Panic = 1,
|
|
17962
|
+
OOG = 2, // out-of-gas
|
|
17963
|
+
}
|
|
18006
17964
|
|
|
18007
|
-
|
|
18008
|
-
|
|
17965
|
+
/** A utility function to easily trace a bunch of registers. */
|
|
17966
|
+
declare function traceRegisters(...regs: number[]) {
|
|
17967
|
+
return regs.map(tryAsRegisterIndex);
|
|
17968
|
+
}
|
|
18009
17969
|
|
|
18010
|
-
|
|
18011
|
-
|
|
18012
|
-
|
|
18013
|
-
|
|
18014
|
-
registers: Registers,
|
|
18015
|
-
): Promise<Result$2<MachineResult, NoMachineError>>;
|
|
17970
|
+
/** An interface for a host call implementation */
|
|
17971
|
+
interface HostCallHandler {
|
|
17972
|
+
/** Index of that host call (i.e. what PVM invokes via `ecalli`) */
|
|
17973
|
+
readonly index: HostCallIndex;
|
|
18016
17974
|
|
|
18017
17975
|
/**
|
|
18018
|
-
*
|
|
17976
|
+
* The gas cost of invocation of that host call.
|
|
18019
17977
|
*
|
|
18020
|
-
*
|
|
17978
|
+
* NOTE: `((reg: IHostCallRegisters) => Gas)` function is for compatibility reasons: pre GP 0.7.2
|
|
18021
17979
|
*/
|
|
18022
|
-
|
|
17980
|
+
readonly basicGasCost: SmallGas | ((reg: IHostCallRegisters) => Gas);
|
|
18023
17981
|
|
|
18024
|
-
/**
|
|
18025
|
-
|
|
17982
|
+
/** Currently executing service id. */
|
|
17983
|
+
readonly currentServiceId: U32;
|
|
18026
17984
|
|
|
18027
|
-
/**
|
|
18028
|
-
|
|
18029
|
-
machineIndex: MachineId,
|
|
18030
|
-
pageStart: U64,
|
|
18031
|
-
pageCount: U64,
|
|
18032
|
-
requestType: MemoryOperation | null,
|
|
18033
|
-
): Promise<Result$2<OK, PagesError>>;
|
|
18034
|
-
}
|
|
17985
|
+
/** Input&Output registers that we should add to tracing log. */
|
|
17986
|
+
readonly tracedRegisters: RegisterIndex[];
|
|
18035
17987
|
|
|
18036
|
-
|
|
18037
|
-
|
|
17988
|
+
/**
|
|
17989
|
+
* Actually execute the host call.
|
|
17990
|
+
*
|
|
17991
|
+
* NOTE the call is ALLOWED and expected to modify registers and memory.
|
|
17992
|
+
*/
|
|
17993
|
+
execute(gas: GasCounter, regs: IHostCallRegisters, memory: IHostCallMemory): Promise<undefined | PvmExecution>;
|
|
17994
|
+
}
|
|
18038
17995
|
|
|
18039
|
-
/**
|
|
18040
|
-
|
|
18041
|
-
|
|
17996
|
+
/** Container for all available host calls. */
|
|
17997
|
+
declare class HostCallsManager {
|
|
17998
|
+
private readonly hostCalls = new Map<HostCallIndex, HostCallHandler>();
|
|
17999
|
+
private readonly missing;
|
|
18042
18000
|
|
|
18043
|
-
|
|
18044
|
-
|
|
18045
|
-
|
|
18046
|
-
|
|
18047
|
-
|
|
18048
|
-
|
|
18049
|
-
|
|
18050
|
-
|
|
18051
|
-
new Map();
|
|
18052
|
-
/** New validators data. */
|
|
18053
|
-
public validatorsData: PerValidator<ValidatorData> | null = null;
|
|
18054
|
-
/** Updated priviliged services. */
|
|
18055
|
-
public privilegedServices: PrivilegedServices | null = null;
|
|
18001
|
+
constructor({
|
|
18002
|
+
missing,
|
|
18003
|
+
handlers = [],
|
|
18004
|
+
}: {
|
|
18005
|
+
missing: HostCallHandler;
|
|
18006
|
+
handlers?: HostCallHandler[];
|
|
18007
|
+
}) {
|
|
18008
|
+
this.missing = missing;
|
|
18056
18009
|
|
|
18057
|
-
|
|
18058
|
-
|
|
18059
|
-
|
|
18060
|
-
|
|
18061
|
-
|
|
18062
|
-
/** Yielded accumulation root. */
|
|
18063
|
-
public readonly yieldedRoots: Map<ServiceId, OpaqueHash> = new Map(),
|
|
18064
|
-
) {}
|
|
18010
|
+
for (const handler of handlers) {
|
|
18011
|
+
check`${this.hostCalls.get(handler.index) === undefined} Overwriting host call handler at index ${handler.index}`;
|
|
18012
|
+
this.hostCalls.set(handler.index, handler);
|
|
18013
|
+
}
|
|
18014
|
+
}
|
|
18065
18015
|
|
|
18066
|
-
/**
|
|
18067
|
-
|
|
18068
|
-
return
|
|
18069
|
-
{
|
|
18070
|
-
servicesUpdates: [],
|
|
18071
|
-
servicesRemoved: [],
|
|
18072
|
-
preimages: [],
|
|
18073
|
-
storage: [],
|
|
18074
|
-
},
|
|
18075
|
-
[],
|
|
18076
|
-
);
|
|
18016
|
+
/** Get a host call by index. */
|
|
18017
|
+
get(hostCallIndex: HostCallIndex): HostCallHandler {
|
|
18018
|
+
return this.hostCalls.get(hostCallIndex) ?? this.missing;
|
|
18077
18019
|
}
|
|
18078
18020
|
|
|
18079
|
-
|
|
18080
|
-
|
|
18081
|
-
|
|
18082
|
-
|
|
18083
|
-
|
|
18084
|
-
|
|
18085
|
-
|
|
18086
|
-
|
|
18021
|
+
traceHostCall(
|
|
18022
|
+
context: string,
|
|
18023
|
+
hostCallIndex: HostCallIndex,
|
|
18024
|
+
hostCallHandler: HostCallHandler,
|
|
18025
|
+
registers: IHostCallRegisters,
|
|
18026
|
+
gas: Gas,
|
|
18027
|
+
) {
|
|
18028
|
+
const { currentServiceId } = hostCallHandler;
|
|
18029
|
+
const requested = hostCallIndex !== hostCallHandler.index ? ` (${hostCallIndex})` : "";
|
|
18030
|
+
const name = `${hostCallHandler.constructor.name}:${hostCallHandler.index}`;
|
|
18031
|
+
const registerValues = hostCallHandler.tracedRegisters
|
|
18032
|
+
.map((idx) => [idx.toString().padStart(2, "0"), registers.get(idx)] as const)
|
|
18033
|
+
.filter((v) => v[1] !== 0n)
|
|
18034
|
+
.map(([idx, value]) => {
|
|
18035
|
+
return `r${idx}=${value} (0x${value.toString(16)})`;
|
|
18036
|
+
})
|
|
18037
|
+
.join(", ");
|
|
18038
|
+
logger.insane`[${currentServiceId}] ${context} ${name}${requested}. Gas: ${gas}. Regs: ${registerValues}.`;
|
|
18087
18039
|
}
|
|
18040
|
+
}
|
|
18088
18041
|
|
|
18089
|
-
|
|
18090
|
-
static copyFrom(from: AccumulationStateUpdate): AccumulationStateUpdate {
|
|
18091
|
-
const serviceUpdates: ServicesUpdate = {
|
|
18092
|
-
servicesUpdates: [...from.services.servicesUpdates],
|
|
18093
|
-
servicesRemoved: [...from.services.servicesRemoved],
|
|
18094
|
-
preimages: [...from.services.preimages],
|
|
18095
|
-
storage: [...from.services.storage],
|
|
18096
|
-
};
|
|
18097
|
-
const transfers = [...from.transfers];
|
|
18098
|
-
const update = new AccumulationStateUpdate(serviceUpdates, transfers, new Map(from.yieldedRoots));
|
|
18042
|
+
type ResolveFn = (pvm: Interpreter) => void;
|
|
18099
18043
|
|
|
18100
|
-
|
|
18101
|
-
|
|
18102
|
-
|
|
18103
|
-
}
|
|
18044
|
+
declare class InterpreterInstanceManager {
|
|
18045
|
+
private instances: Interpreter[] = [];
|
|
18046
|
+
private waitingQueue: ResolveFn[] = [];
|
|
18104
18047
|
|
|
18105
|
-
|
|
18106
|
-
|
|
18048
|
+
constructor(noOfPvmInstances: number) {
|
|
18049
|
+
for (let i = 0; i < noOfPvmInstances; i++) {
|
|
18050
|
+
this.instances.push(
|
|
18051
|
+
new Interpreter({
|
|
18052
|
+
useSbrkGas: false,
|
|
18053
|
+
}),
|
|
18054
|
+
);
|
|
18107
18055
|
}
|
|
18056
|
+
}
|
|
18108
18057
|
|
|
18109
|
-
|
|
18110
|
-
|
|
18111
|
-
|
|
18112
|
-
|
|
18113
|
-
});
|
|
18058
|
+
async getInstance(): Promise<Interpreter> {
|
|
18059
|
+
const instance = this.instances.pop();
|
|
18060
|
+
if (instance !== undefined) {
|
|
18061
|
+
return Promise.resolve(instance);
|
|
18114
18062
|
}
|
|
18115
|
-
return
|
|
18063
|
+
return new Promise((resolve) => {
|
|
18064
|
+
this.waitingQueue.push(resolve);
|
|
18065
|
+
});
|
|
18116
18066
|
}
|
|
18117
18067
|
|
|
18118
|
-
|
|
18119
|
-
|
|
18120
|
-
|
|
18121
|
-
|
|
18122
|
-
|
|
18068
|
+
releaseInstance(pvm: Interpreter) {
|
|
18069
|
+
const waiting = this.waitingQueue.shift();
|
|
18070
|
+
if (waiting !== undefined) {
|
|
18071
|
+
return waiting(pvm);
|
|
18072
|
+
}
|
|
18073
|
+
this.instances.push(pvm);
|
|
18123
18074
|
}
|
|
18124
18075
|
}
|
|
18125
18076
|
|
|
18126
|
-
|
|
18127
|
-
|
|
18128
|
-
|
|
18129
|
-
|
|
18130
|
-
|
|
18131
|
-
|
|
18132
|
-
constructor(
|
|
18133
|
-
/** Original (unmodified state). */
|
|
18134
|
-
public readonly state: T,
|
|
18135
|
-
stateUpdate?: AccumulationStateUpdate,
|
|
18077
|
+
declare class ReturnValue {
|
|
18078
|
+
private constructor(
|
|
18079
|
+
public consumedGas: Gas,
|
|
18080
|
+
public status: Status | null,
|
|
18081
|
+
public memorySlice: Uint8Array | null,
|
|
18136
18082
|
) {
|
|
18137
|
-
|
|
18138
|
-
|
|
18083
|
+
check`
|
|
18084
|
+
${(status === null && memorySlice !== null) || (status !== null && memorySlice === null)}
|
|
18085
|
+
'status' and 'memorySlice' must not both be null or both be non-null — exactly one must be provided
|
|
18086
|
+
`;
|
|
18139
18087
|
}
|
|
18140
18088
|
|
|
18141
|
-
|
|
18142
|
-
|
|
18143
|
-
|
|
18144
|
-
* NOTE the info may be updated compared to what is in the state.
|
|
18145
|
-
*
|
|
18146
|
-
* Takes into account ejected and newly created services as well.
|
|
18147
|
-
*/
|
|
18148
|
-
getServiceInfo(destination: ServiceId | null): ServiceAccountInfo | null {
|
|
18149
|
-
if (destination === null) {
|
|
18150
|
-
return null;
|
|
18151
|
-
}
|
|
18152
|
-
|
|
18153
|
-
const maybeNewService = this.stateUpdate.services.servicesUpdates.find(
|
|
18154
|
-
(update) => update.serviceId === destination,
|
|
18155
|
-
);
|
|
18156
|
-
|
|
18157
|
-
if (maybeNewService !== undefined) {
|
|
18158
|
-
return maybeNewService.action.account;
|
|
18159
|
-
}
|
|
18160
|
-
|
|
18161
|
-
const maybeService = this.state.getService(destination);
|
|
18162
|
-
if (maybeService === null) {
|
|
18163
|
-
return null;
|
|
18164
|
-
}
|
|
18089
|
+
static fromStatus(consumedGas: Gas, status: Status) {
|
|
18090
|
+
return new ReturnValue(consumedGas, status, null);
|
|
18091
|
+
}
|
|
18165
18092
|
|
|
18166
|
-
|
|
18093
|
+
static fromMemorySlice(consumedGas: Gas, memorySlice: Uint8Array) {
|
|
18094
|
+
return new ReturnValue(consumedGas, null, memorySlice);
|
|
18167
18095
|
}
|
|
18168
18096
|
|
|
18169
|
-
|
|
18170
|
-
|
|
18171
|
-
|
|
18172
|
-
return item.value;
|
|
18173
|
-
}
|
|
18097
|
+
hasMemorySlice(): this is this & { status: null; memorySlice: Uint8Array } {
|
|
18098
|
+
return this.memorySlice instanceof Uint8Array && this.status === null;
|
|
18099
|
+
}
|
|
18174
18100
|
|
|
18175
|
-
|
|
18176
|
-
return
|
|
18101
|
+
hasStatus(): this is this & { status: Status; memorySlice: null } {
|
|
18102
|
+
return !this.hasMemorySlice();
|
|
18177
18103
|
}
|
|
18104
|
+
}
|
|
18105
|
+
declare class HostCalls {
|
|
18106
|
+
constructor(
|
|
18107
|
+
private pvmInstanceManager: InterpreterInstanceManager,
|
|
18108
|
+
private hostCalls: HostCallsManager,
|
|
18109
|
+
) {}
|
|
18178
18110
|
|
|
18179
|
-
|
|
18180
|
-
|
|
18181
|
-
|
|
18182
|
-
|
|
18183
|
-
* NOTE: Does not check if the preimage is available, we just check
|
|
18184
|
-
* the existence in `preimages` map.
|
|
18185
|
-
*/
|
|
18186
|
-
hasPreimage(serviceId: ServiceId, hash: PreimageHash): boolean {
|
|
18187
|
-
const providedPreimage = this.stateUpdate.services.preimages.find(
|
|
18188
|
-
// we ignore the action here, since if there is <any> update on that
|
|
18189
|
-
// hash it means it has to exist, right?
|
|
18190
|
-
(p) => p.serviceId === serviceId && p.hash.isEqualTo(hash),
|
|
18191
|
-
);
|
|
18192
|
-
if (providedPreimage !== undefined) {
|
|
18193
|
-
return true;
|
|
18111
|
+
private getReturnValue(status: Status, pvmInstance: Interpreter): ReturnValue {
|
|
18112
|
+
const gasConsumed = pvmInstance.getGasConsumed();
|
|
18113
|
+
if (status === Status.OOG) {
|
|
18114
|
+
return ReturnValue.fromStatus(gasConsumed, status);
|
|
18194
18115
|
}
|
|
18195
18116
|
|
|
18196
|
-
|
|
18197
|
-
|
|
18198
|
-
|
|
18199
|
-
|
|
18200
|
-
|
|
18117
|
+
if (status === Status.HALT) {
|
|
18118
|
+
const memory = pvmInstance.getMemory();
|
|
18119
|
+
const regs = pvmInstance.getRegisters();
|
|
18120
|
+
const maybeAddress = regs.getLowerU32(7);
|
|
18121
|
+
const maybeLength = regs.getLowerU32(8);
|
|
18201
18122
|
|
|
18202
|
-
|
|
18203
|
-
|
|
18123
|
+
const result = safeAllocUint8Array(maybeLength);
|
|
18124
|
+
const startAddress = tryAsMemoryIndex(maybeAddress);
|
|
18125
|
+
const loadResult = memory.loadInto(result, startAddress);
|
|
18204
18126
|
|
|
18205
|
-
|
|
18206
|
-
|
|
18207
|
-
|
|
18208
|
-
|
|
18209
|
-
|
|
18210
|
-
if (freshlyProvided !== undefined && freshlyProvided.action.kind === UpdatePreimageKind.Provide) {
|
|
18211
|
-
return freshlyProvided.action.preimage.blob;
|
|
18127
|
+
if (loadResult.isError) {
|
|
18128
|
+
return ReturnValue.fromMemorySlice(gasConsumed, new Uint8Array());
|
|
18129
|
+
}
|
|
18130
|
+
|
|
18131
|
+
return ReturnValue.fromMemorySlice(gasConsumed, result);
|
|
18212
18132
|
}
|
|
18213
18133
|
|
|
18214
|
-
|
|
18215
|
-
return service?.getPreimage(hash) ?? null;
|
|
18134
|
+
return ReturnValue.fromStatus(gasConsumed, Status.PANIC);
|
|
18216
18135
|
}
|
|
18217
18136
|
|
|
18218
|
-
|
|
18219
|
-
|
|
18220
|
-
|
|
18221
|
-
|
|
18222
|
-
|
|
18223
|
-
|
|
18224
|
-
): LookupHistoryItem | null {
|
|
18225
|
-
// TODO [ToDr] This is most likely wrong. We may have `provide` and `remove` within
|
|
18226
|
-
// the same state update. We should however switch to proper "updated state"
|
|
18227
|
-
// representation soon.
|
|
18228
|
-
const updatedPreimage = this.stateUpdate.services.preimages.findLast(
|
|
18229
|
-
(update) => update.serviceId === serviceId && update.hash.isEqualTo(hash) && BigInt(update.length) === length,
|
|
18230
|
-
);
|
|
18231
|
-
|
|
18232
|
-
const stateFallback = () => {
|
|
18233
|
-
// fallback to state lookup
|
|
18234
|
-
const service = this.state.getService(serviceId);
|
|
18235
|
-
const lenU32 = preimageLenAsU32(length);
|
|
18236
|
-
if (lenU32 === null || service === null) {
|
|
18237
|
-
return null;
|
|
18137
|
+
private async execute(pvmInstance: Interpreter) {
|
|
18138
|
+
pvmInstance.runProgram();
|
|
18139
|
+
for (;;) {
|
|
18140
|
+
let status = pvmInstance.getStatus();
|
|
18141
|
+
if (status !== Status.HOST) {
|
|
18142
|
+
return this.getReturnValue(status, pvmInstance);
|
|
18238
18143
|
}
|
|
18144
|
+
check`
|
|
18145
|
+
${pvmInstance.getExitParam() !== null}
|
|
18146
|
+
"We know that the exit param is not null, because the status is 'Status.HOST'
|
|
18147
|
+
`;
|
|
18148
|
+
const hostCallIndex = pvmInstance.getExitParam() ?? -1;
|
|
18149
|
+
const gas = pvmInstance.getGasCounter();
|
|
18150
|
+
const regs = new HostCallRegisters(pvmInstance.getRegisters());
|
|
18151
|
+
const memory = new HostCallMemory(pvmInstance.getMemory());
|
|
18152
|
+
const index = tryAsHostCallIndex(hostCallIndex);
|
|
18239
18153
|
|
|
18240
|
-
const
|
|
18241
|
-
|
|
18242
|
-
|
|
18243
|
-
|
|
18244
|
-
|
|
18245
|
-
|
|
18246
|
-
}
|
|
18154
|
+
const hostCall = this.hostCalls.get(index);
|
|
18155
|
+
const gasBefore = gas.get();
|
|
18156
|
+
// NOTE: `basicGasCost(regs)` function is for compatibility reasons: pre GP 0.7.2
|
|
18157
|
+
const basicGasCost =
|
|
18158
|
+
typeof hostCall.basicGasCost === "number" ? hostCall.basicGasCost : hostCall.basicGasCost(regs);
|
|
18159
|
+
const underflow = gas.sub(basicGasCost);
|
|
18247
18160
|
|
|
18248
|
-
|
|
18249
|
-
|
|
18250
|
-
|
|
18251
|
-
|
|
18252
|
-
return new LookupHistoryItem(hash, updatedPreimage.length, tryAsLookupHistorySlots([currentTimeslot]));
|
|
18161
|
+
const pcLog = `[PC: ${pvmInstance.getPC()}]`;
|
|
18162
|
+
if (underflow) {
|
|
18163
|
+
this.hostCalls.traceHostCall(`${pcLog} OOG`, index, hostCall, regs, gas.get());
|
|
18164
|
+
return ReturnValue.fromStatus(pvmInstance.getGasConsumed(), Status.OOG);
|
|
18253
18165
|
}
|
|
18254
|
-
|
|
18255
|
-
|
|
18256
|
-
|
|
18257
|
-
|
|
18258
|
-
|
|
18259
|
-
|
|
18166
|
+
this.hostCalls.traceHostCall(`${pcLog} Invoking`, index, hostCall, regs, gasBefore);
|
|
18167
|
+
const result = await hostCall.execute(gas, regs, memory);
|
|
18168
|
+
this.hostCalls.traceHostCall(
|
|
18169
|
+
result === undefined ? `${pcLog} Result` : `${pcLog} Status(${PvmExecution[result]})`,
|
|
18170
|
+
index,
|
|
18171
|
+
hostCall,
|
|
18172
|
+
regs,
|
|
18173
|
+
gas.get(),
|
|
18174
|
+
);
|
|
18260
18175
|
|
|
18261
|
-
|
|
18262
|
-
|
|
18263
|
-
|
|
18264
|
-
return action.item;
|
|
18176
|
+
if (result === PvmExecution.Halt) {
|
|
18177
|
+
status = Status.HALT;
|
|
18178
|
+
return this.getReturnValue(status, pvmInstance);
|
|
18265
18179
|
}
|
|
18266
|
-
}
|
|
18267
18180
|
|
|
18268
|
-
|
|
18269
|
-
|
|
18181
|
+
if (result === PvmExecution.Panic) {
|
|
18182
|
+
status = Status.PANIC;
|
|
18183
|
+
return this.getReturnValue(status, pvmInstance);
|
|
18184
|
+
}
|
|
18270
18185
|
|
|
18271
|
-
|
|
18186
|
+
if (result === PvmExecution.OOG) {
|
|
18187
|
+
status = Status.OOG;
|
|
18188
|
+
return this.getReturnValue(status, pvmInstance);
|
|
18189
|
+
}
|
|
18272
18190
|
|
|
18273
|
-
|
|
18274
|
-
|
|
18275
|
-
|
|
18276
|
-
|
|
18277
|
-
|
|
18278
|
-
serviceId,
|
|
18279
|
-
storage: StorageItem.create({ key, value }),
|
|
18280
|
-
});
|
|
18191
|
+
if (result === undefined) {
|
|
18192
|
+
pvmInstance.runProgram();
|
|
18193
|
+
status = pvmInstance.getStatus();
|
|
18194
|
+
continue;
|
|
18195
|
+
}
|
|
18281
18196
|
|
|
18282
|
-
|
|
18283
|
-
|
|
18284
|
-
);
|
|
18285
|
-
const count = index === -1 ? 0 : 1;
|
|
18286
|
-
this.stateUpdate.services.storage.splice(index, count, update);
|
|
18197
|
+
assertNever(result);
|
|
18198
|
+
}
|
|
18287
18199
|
}
|
|
18288
18200
|
|
|
18289
|
-
|
|
18290
|
-
|
|
18291
|
-
|
|
18292
|
-
|
|
18293
|
-
|
|
18294
|
-
|
|
18295
|
-
|
|
18296
|
-
this.
|
|
18201
|
+
async runProgram(
|
|
18202
|
+
rawProgram: Uint8Array,
|
|
18203
|
+
initialPc: number,
|
|
18204
|
+
initialGas: Gas,
|
|
18205
|
+
maybeRegisters?: Registers,
|
|
18206
|
+
maybeMemory?: Memory,
|
|
18207
|
+
): Promise<ReturnValue> {
|
|
18208
|
+
const pvmInstance = await this.pvmInstanceManager.getInstance();
|
|
18209
|
+
pvmInstance.reset(rawProgram, initialPc, initialGas, maybeRegisters, maybeMemory);
|
|
18210
|
+
try {
|
|
18211
|
+
return await this.execute(pvmInstance);
|
|
18212
|
+
} finally {
|
|
18213
|
+
this.pvmInstanceManager.releaseInstance(pvmInstance);
|
|
18214
|
+
}
|
|
18297
18215
|
}
|
|
18216
|
+
}
|
|
18298
18217
|
|
|
18299
|
-
|
|
18300
|
-
|
|
18301
|
-
|
|
18302
|
-
|
|
18303
|
-
|
|
18304
|
-
|
|
18305
|
-
|
|
18306
|
-
|
|
18307
|
-
|
|
18308
|
-
|
|
18309
|
-
|
|
18218
|
+
type index$7_HostCallHandler = HostCallHandler;
|
|
18219
|
+
type index$7_HostCallMemory = HostCallMemory;
|
|
18220
|
+
declare const index$7_HostCallMemory: typeof HostCallMemory;
|
|
18221
|
+
type index$7_HostCallRegisters = HostCallRegisters;
|
|
18222
|
+
declare const index$7_HostCallRegisters: typeof HostCallRegisters;
|
|
18223
|
+
type index$7_IHostCallMemory = IHostCallMemory;
|
|
18224
|
+
type index$7_IHostCallRegisters = IHostCallRegisters;
|
|
18225
|
+
type index$7_PvmExecution = PvmExecution;
|
|
18226
|
+
declare const index$7_PvmExecution: typeof PvmExecution;
|
|
18227
|
+
declare const index$7_traceRegisters: typeof traceRegisters;
|
|
18228
|
+
declare const index$7_tryAsHostCallIndex: typeof tryAsHostCallIndex;
|
|
18229
|
+
declare namespace index$7 {
|
|
18230
|
+
export { index$7_HostCallMemory as HostCallMemory, index$7_HostCallRegisters as HostCallRegisters, HostCallsManager as HostCalls, index$7_PvmExecution as PvmExecution, HostCalls as PvmHostCallExtension, InterpreterInstanceManager as PvmInstanceManager, index$7_traceRegisters as traceRegisters, index$7_tryAsHostCallIndex as tryAsHostCallIndex };
|
|
18231
|
+
export type { index$7_HostCallHandler as HostCallHandler, index$7_IHostCallMemory as IHostCallMemory, index$7_IHostCallRegisters as IHostCallRegisters };
|
|
18232
|
+
}
|
|
18310
18233
|
|
|
18311
|
-
|
|
18312
|
-
|
|
18313
|
-
|
|
18314
|
-
|
|
18234
|
+
/**
|
|
18235
|
+
* Program counter is a 64-bit unsigned integer that points to the next instruction
|
|
18236
|
+
*
|
|
18237
|
+
* https://graypaper.fluffylabs.dev/#/1c979cb/2e3f012e3f01?v=0.7.1
|
|
18238
|
+
*/
|
|
18239
|
+
type ProgramCounter = Opaque<U64, "ProgramCounter[u64]">;
|
|
18240
|
+
/** Convert a number into ProgramCounter. */
|
|
18241
|
+
declare const tryAsProgramCounter = (v: number | bigint): ProgramCounter => asOpaqueType(tryAsU64(v));
|
|
18315
18242
|
|
|
18316
|
-
|
|
18317
|
-
|
|
18318
|
-
|
|
18319
|
-
|
|
18243
|
+
/** Running PVM instance identifier. */
|
|
18244
|
+
type MachineId = Opaque<U64, "MachineId[u64]">;
|
|
18245
|
+
/** Convert a number into PVM instance identifier. */
|
|
18246
|
+
declare const tryAsMachineId = (v: number | bigint): MachineId => asOpaqueType(tryAsU64(v));
|
|
18320
18247
|
|
|
18321
|
-
|
|
18322
|
-
|
|
18323
|
-
|
|
18324
|
-
|
|
18325
|
-
|
|
18326
|
-
|
|
18327
|
-
|
|
18328
|
-
|
|
18329
|
-
|
|
18330
|
-
return Result.ok(OK);
|
|
18248
|
+
declare class MachineInstance {
|
|
18249
|
+
async run(gas: BigGas, registers: Registers): Promise<MachineResult> {
|
|
18250
|
+
return {
|
|
18251
|
+
result: {
|
|
18252
|
+
status: Status.OK,
|
|
18253
|
+
},
|
|
18254
|
+
gas,
|
|
18255
|
+
registers,
|
|
18256
|
+
};
|
|
18331
18257
|
}
|
|
18258
|
+
}
|
|
18332
18259
|
|
|
18333
|
-
|
|
18334
|
-
|
|
18335
|
-
|
|
18336
|
-
|
|
18337
|
-
|
|
18338
|
-
if (existingItem?.action.kind === UpdateServiceKind.Create) {
|
|
18339
|
-
this.stateUpdate.services.servicesUpdates.splice(
|
|
18340
|
-
idx,
|
|
18341
|
-
toRemove,
|
|
18342
|
-
UpdateService.create({
|
|
18343
|
-
serviceId,
|
|
18344
|
-
serviceInfo: newInfo,
|
|
18345
|
-
lookupHistory: existingItem.action.lookupHistory,
|
|
18346
|
-
}),
|
|
18347
|
-
);
|
|
18348
|
-
|
|
18349
|
-
return;
|
|
18260
|
+
type MachineStatus =
|
|
18261
|
+
| {
|
|
18262
|
+
status: typeof Status.HOST;
|
|
18263
|
+
hostCallIndex: U64;
|
|
18350
18264
|
}
|
|
18351
|
-
|
|
18352
|
-
|
|
18353
|
-
|
|
18354
|
-
toRemove,
|
|
18355
|
-
UpdateService.update({
|
|
18356
|
-
serviceId,
|
|
18357
|
-
serviceInfo: newInfo,
|
|
18358
|
-
}),
|
|
18359
|
-
);
|
|
18360
|
-
}
|
|
18361
|
-
|
|
18362
|
-
getPrivilegedServices() {
|
|
18363
|
-
if (this.stateUpdate.privilegedServices !== null) {
|
|
18364
|
-
return this.stateUpdate.privilegedServices;
|
|
18265
|
+
| {
|
|
18266
|
+
status: typeof Status.FAULT;
|
|
18267
|
+
address: U64;
|
|
18365
18268
|
}
|
|
18269
|
+
| {
|
|
18270
|
+
status: typeof Status.OK | typeof Status.HALT | typeof Status.PANIC | typeof Status.OOG;
|
|
18271
|
+
};
|
|
18366
18272
|
|
|
18367
|
-
|
|
18368
|
-
|
|
18273
|
+
/** Data returned by a machine invocation. */
|
|
18274
|
+
type MachineResult = {
|
|
18275
|
+
result: MachineStatus;
|
|
18276
|
+
gas: BigGas;
|
|
18277
|
+
registers: Registers;
|
|
18278
|
+
};
|
|
18279
|
+
|
|
18280
|
+
/** Types of possbile operations to request by Pages host call. */
|
|
18281
|
+
declare enum MemoryOperation {
|
|
18282
|
+
/** Zeroes memory and set access to unreadable. */
|
|
18283
|
+
Void = 0,
|
|
18284
|
+
/** Zeroes memory and set access to read-only. */
|
|
18285
|
+
ZeroRead = 1,
|
|
18286
|
+
/** Zeroes memory and set access to read-write. */
|
|
18287
|
+
ZeroWrite = 2,
|
|
18288
|
+
/** Preserve memory and set access to read-only. */
|
|
18289
|
+
Read = 3,
|
|
18290
|
+
/** Preserve memory and set access to read-write. */
|
|
18291
|
+
Write = 4,
|
|
18369
18292
|
}
|
|
18370
18293
|
|
|
18371
|
-
|
|
18372
|
-
|
|
18373
|
-
|
|
18294
|
+
/** Convert a number into MemoryOperation or null (if invalid). */
|
|
18295
|
+
declare const toMemoryOperation = (v: number | bigint): MemoryOperation | null =>
|
|
18296
|
+
v <= MemoryOperation.Write && v >= MemoryOperation.Void ? Number(v) : null;
|
|
18297
|
+
|
|
18298
|
+
/** An error that may occur during `peek` or `poke` host call. */
|
|
18299
|
+
declare enum PeekPokeError {
|
|
18300
|
+
/** Source page fault. */
|
|
18301
|
+
SourcePageFault = 0,
|
|
18302
|
+
/** Destination page fault. */
|
|
18303
|
+
DestinationPageFault = 1,
|
|
18304
|
+
/** No machine under given machine index. */
|
|
18305
|
+
NoMachine = 2,
|
|
18374
18306
|
}
|
|
18375
18307
|
|
|
18376
|
-
|
|
18377
|
-
|
|
18378
|
-
|
|
18379
|
-
|
|
18380
|
-
|
|
18381
|
-
|
|
18382
|
-
/** The return value indicating an item does not exist. */
|
|
18383
|
-
NONE: tryAsU64(0xffff_ffff_ffff_ffffn), // 2**64 - 1
|
|
18384
|
-
/** Name unknown. */
|
|
18385
|
-
WHAT: tryAsU64(0xffff_ffff_ffff_fffen), // 2**64 - 2
|
|
18386
|
-
/** The inner PVM memory index provided for reading/writing is not accessible. */
|
|
18387
|
-
OOB: tryAsU64(0xffff_ffff_ffff_fffdn), // 2**64 - 3
|
|
18388
|
-
/** Index unknown. */
|
|
18389
|
-
WHO: tryAsU64(0xffff_ffff_ffff_fffcn), // 2**64 - 4
|
|
18390
|
-
/** Storage full or resource already allocated. */
|
|
18391
|
-
FULL: tryAsU64(0xffff_ffff_ffff_fffbn), // 2**64 - 5
|
|
18392
|
-
/** Core index unknown. */
|
|
18393
|
-
CORE: tryAsU64(0xffff_ffff_ffff_fffan), // 2**64 - 6
|
|
18394
|
-
/** Insufficient funds. */
|
|
18395
|
-
CASH: tryAsU64(0xffff_ffff_ffff_fff9n), // 2**64 - 7
|
|
18396
|
-
/** Gas limit too low. */
|
|
18397
|
-
LOW: tryAsU64(0xffff_ffff_ffff_fff8n), // 2**64 - 8
|
|
18398
|
-
/** The item is already solicited, cannot be forgotten or the operation is invalid due to privilege level. */
|
|
18399
|
-
HUH: tryAsU64(0xffff_ffff_ffff_fff7n), // 2**64 - 9
|
|
18400
|
-
/** The return value indicating general success. */
|
|
18401
|
-
OK: tryAsU64(0n),
|
|
18402
|
-
} as const;
|
|
18308
|
+
declare enum ZeroVoidError {
|
|
18309
|
+
/** No machine under given machine index. */
|
|
18310
|
+
NoMachine = 0,
|
|
18311
|
+
/** Attempting to void or zero non-accessible page. */
|
|
18312
|
+
InvalidPage = 1,
|
|
18313
|
+
}
|
|
18403
18314
|
|
|
18404
|
-
|
|
18405
|
-
|
|
18406
|
-
|
|
18407
|
-
|
|
18315
|
+
declare enum PagesError {
|
|
18316
|
+
/** No machine under given machine index. */
|
|
18317
|
+
NoMachine = 0,
|
|
18318
|
+
/** Invalid memory operation. */
|
|
18319
|
+
InvalidOperation = 1,
|
|
18320
|
+
/** Attempting to change non-accessible page or trying to preserve value of voided page. */
|
|
18321
|
+
InvalidPage = 2,
|
|
18408
18322
|
}
|
|
18409
18323
|
|
|
18410
|
-
|
|
18411
|
-
|
|
18324
|
+
/** Error machine is not found. */
|
|
18325
|
+
declare const NoMachineError = Symbol("Machine index not found.");
|
|
18326
|
+
type NoMachineError = typeof NoMachineError;
|
|
18412
18327
|
|
|
18413
|
-
|
|
18414
|
-
|
|
18415
|
-
|
|
18416
|
-
}
|
|
18328
|
+
/** Too many segments already exported. */
|
|
18329
|
+
declare const SegmentExportError = Symbol("Too many segments already exported.");
|
|
18330
|
+
type SegmentExportError = typeof SegmentExportError;
|
|
18417
18331
|
|
|
18418
|
-
|
|
18419
|
-
|
|
18420
|
-
|
|
18332
|
+
/** Host functions external invocations available during refine phase. */
|
|
18333
|
+
interface RefineExternalities {
|
|
18334
|
+
/** Forget a previously started nested VM. */
|
|
18335
|
+
machineExpunge(machineIndex: MachineId): Promise<Result$2<ProgramCounter, NoMachineError>>;
|
|
18421
18336
|
|
|
18422
|
-
|
|
18423
|
-
|
|
18337
|
+
/** Set given range of pages as non-accessible and re-initialize them with zeros. */
|
|
18338
|
+
machineVoidPages(machineIndex: MachineId, pageStart: U64, pageCount: U64): Promise<Result$2<OK, ZeroVoidError>>;
|
|
18424
18339
|
|
|
18425
|
-
|
|
18426
|
-
|
|
18427
|
-
|
|
18428
|
-
|
|
18340
|
+
/** Set given range of pages as writeable and initialize them with zeros. */
|
|
18341
|
+
machineZeroPages(machineIndex: MachineId, pageStart: U64, pageCount: U64): Promise<Result$2<OK, ZeroVoidError>>;
|
|
18342
|
+
|
|
18343
|
+
/** Copy a fragment of memory from `machineIndex` into given destination memory. */
|
|
18344
|
+
machinePeekFrom(
|
|
18345
|
+
machineIndex: MachineId,
|
|
18346
|
+
destinationStart: U64,
|
|
18347
|
+
sourceStart: U64,
|
|
18348
|
+
length: U64,
|
|
18349
|
+
destination: IHostCallMemory,
|
|
18350
|
+
): Promise<Result$2<OK, PeekPokeError>>;
|
|
18351
|
+
|
|
18352
|
+
/** Write a fragment of memory into `machineIndex` from given source memory. */
|
|
18353
|
+
machinePokeInto(
|
|
18354
|
+
machineIndex: MachineId,
|
|
18355
|
+
sourceStart: U64,
|
|
18356
|
+
destinationStart: U64,
|
|
18357
|
+
length: U64,
|
|
18358
|
+
source: IHostCallMemory,
|
|
18359
|
+
): Promise<Result$2<OK, PeekPokeError>>;
|
|
18360
|
+
|
|
18361
|
+
/** Start an inner PVM instance with given entry point and starting code. */
|
|
18362
|
+
machineInit(code: BytesBlob, programCounter: ProgramCounter): Promise<Result$2<MachineId, ProgramDecoderError>>;
|
|
18363
|
+
|
|
18364
|
+
/** Run a previously initialized PVM instance with given gas and registers. */
|
|
18365
|
+
machineInvoke(
|
|
18366
|
+
machineIndex: MachineId,
|
|
18367
|
+
gas: BigGas,
|
|
18368
|
+
registers: Registers,
|
|
18369
|
+
): Promise<Result$2<MachineResult, NoMachineError>>;
|
|
18370
|
+
|
|
18371
|
+
/**
|
|
18372
|
+
* Export segment for future retrieval.
|
|
18373
|
+
*
|
|
18374
|
+
* Returns the index assigned to that segment or an error if there is too many already exported.
|
|
18375
|
+
*/
|
|
18376
|
+
exportSegment(segment: Segment): Result$2<SegmentIndex, SegmentExportError>;
|
|
18377
|
+
|
|
18378
|
+
/** Lookup a historical preimage. */
|
|
18379
|
+
historicalLookup(serviceId: ServiceId | null, hash: Blake2bHash): Promise<BytesBlob | null>;
|
|
18380
|
+
|
|
18381
|
+
/** Change access to and/or zero the value of memory. */
|
|
18382
|
+
machinePages(
|
|
18383
|
+
machineIndex: MachineId,
|
|
18384
|
+
pageStart: U64,
|
|
18385
|
+
pageCount: U64,
|
|
18386
|
+
requestType: MemoryOperation | null,
|
|
18387
|
+
): Promise<Result$2<OK, PagesError>>;
|
|
18388
|
+
}
|
|
18389
|
+
|
|
18390
|
+
declare const InsufficientFundsError = "insufficient funds";
|
|
18391
|
+
type InsufficientFundsError = typeof InsufficientFundsError;
|
|
18392
|
+
|
|
18393
|
+
/** Update of the state entries coming from accumulation of a single service. */
|
|
18394
|
+
type ServiceStateUpdate = Partial<Pick<State, "privilegedServices" | "authQueues" | "designatedValidatorData">> &
|
|
18395
|
+
ServicesUpdate;
|
|
18429
18396
|
|
|
18430
|
-
|
|
18431
|
-
|
|
18432
|
-
|
|
18397
|
+
/** Deep clone of a map with array. */
|
|
18398
|
+
declare function deepCloneMapWithArray<K, V>(map: Map<K, V[]>): Map<K, V[]> {
|
|
18399
|
+
const cloned: [K, V[]][] = [];
|
|
18433
18400
|
|
|
18434
|
-
|
|
18401
|
+
for (const [k, v] of map.entries()) {
|
|
18402
|
+
cloned.push([k, v.slice()]);
|
|
18435
18403
|
}
|
|
18436
18404
|
|
|
18437
|
-
|
|
18438
|
-
return this.memory;
|
|
18439
|
-
}
|
|
18405
|
+
return new Map(cloned);
|
|
18440
18406
|
}
|
|
18441
18407
|
|
|
18442
|
-
|
|
18443
|
-
|
|
18444
|
-
|
|
18445
|
-
|
|
18408
|
+
/**
|
|
18409
|
+
* State updates that currently accumulating service produced.
|
|
18410
|
+
*
|
|
18411
|
+
* `x_u`: https://graypaper.fluffylabs.dev/#/9a08063/2f31012f3101?v=0.6.6
|
|
18412
|
+
*/
|
|
18413
|
+
declare class AccumulationStateUpdate {
|
|
18414
|
+
/** Updated authorization queues for cores. */
|
|
18415
|
+
public readonly authorizationQueues: Map<CoreIndex, FixedSizeArray<AuthorizerHash, AUTHORIZATION_QUEUE_SIZE>> =
|
|
18416
|
+
new Map();
|
|
18417
|
+
/** New validators data. */
|
|
18418
|
+
public validatorsData: PerValidator<ValidatorData> | null = null;
|
|
18419
|
+
/** Updated priviliged services. */
|
|
18420
|
+
public privilegedServices: PrivilegedServices | null = null;
|
|
18446
18421
|
|
|
18447
|
-
|
|
18448
|
-
|
|
18422
|
+
private constructor(
|
|
18423
|
+
/** Services state updates. */
|
|
18424
|
+
public readonly services: ServicesUpdate,
|
|
18425
|
+
/** Pending transfers. */
|
|
18426
|
+
public transfers: PendingTransfer[],
|
|
18427
|
+
/** Yielded accumulation root. */
|
|
18428
|
+
public readonly yieldedRoots: Map<ServiceId, OpaqueHash> = new Map(),
|
|
18429
|
+
) {}
|
|
18449
18430
|
|
|
18450
|
-
|
|
18451
|
-
|
|
18431
|
+
/** Create new empty state update. */
|
|
18432
|
+
static empty(): AccumulationStateUpdate {
|
|
18433
|
+
return new AccumulationStateUpdate(
|
|
18434
|
+
{
|
|
18435
|
+
created: [],
|
|
18436
|
+
updated: new Map(),
|
|
18437
|
+
removed: [],
|
|
18438
|
+
preimages: new Map(),
|
|
18439
|
+
storage: new Map(),
|
|
18440
|
+
},
|
|
18441
|
+
[],
|
|
18442
|
+
);
|
|
18452
18443
|
}
|
|
18453
18444
|
|
|
18454
|
-
|
|
18455
|
-
|
|
18445
|
+
/** Create a state update with some existing, yet uncommited services updates. */
|
|
18446
|
+
static new(update: ServicesUpdate): AccumulationStateUpdate {
|
|
18447
|
+
return new AccumulationStateUpdate(
|
|
18448
|
+
{
|
|
18449
|
+
...update,
|
|
18450
|
+
},
|
|
18451
|
+
[],
|
|
18452
|
+
);
|
|
18456
18453
|
}
|
|
18457
|
-
}
|
|
18458
18454
|
|
|
18459
|
-
/**
|
|
18460
|
-
|
|
18461
|
-
|
|
18462
|
-
|
|
18455
|
+
/** Create a copy of another `StateUpdate`. Used by checkpoints. */
|
|
18456
|
+
static copyFrom(from: AccumulationStateUpdate): AccumulationStateUpdate {
|
|
18457
|
+
const serviceUpdates: ServicesUpdate = {
|
|
18458
|
+
// shallow copy
|
|
18459
|
+
created: [...from.services.created],
|
|
18460
|
+
updated: new Map(from.services.updated),
|
|
18461
|
+
removed: [...from.services.removed],
|
|
18462
|
+
// deep copy
|
|
18463
|
+
preimages: deepCloneMapWithArray(from.services.preimages),
|
|
18464
|
+
storage: deepCloneMapWithArray(from.services.storage),
|
|
18465
|
+
};
|
|
18466
|
+
const transfers = [...from.transfers];
|
|
18467
|
+
const update = new AccumulationStateUpdate(serviceUpdates, transfers, new Map(from.yieldedRoots));
|
|
18463
18468
|
|
|
18464
|
-
|
|
18465
|
-
|
|
18466
|
-
|
|
18467
|
-
|
|
18468
|
-
*/
|
|
18469
|
-
declare enum PvmExecution {
|
|
18470
|
-
Halt = 0,
|
|
18471
|
-
Panic = 1,
|
|
18472
|
-
OOG = 2, // out-of-gas
|
|
18473
|
-
}
|
|
18469
|
+
// update entries
|
|
18470
|
+
for (const [k, v] of from.authorizationQueues) {
|
|
18471
|
+
update.authorizationQueues.set(k, v);
|
|
18472
|
+
}
|
|
18474
18473
|
|
|
18475
|
-
|
|
18476
|
-
|
|
18477
|
-
|
|
18478
|
-
}
|
|
18474
|
+
if (from.validatorsData !== null) {
|
|
18475
|
+
update.validatorsData = asKnownSize([...from.validatorsData]);
|
|
18476
|
+
}
|
|
18479
18477
|
|
|
18480
|
-
|
|
18481
|
-
|
|
18482
|
-
|
|
18483
|
-
|
|
18478
|
+
if (from.privilegedServices !== null) {
|
|
18479
|
+
update.privilegedServices = PrivilegedServices.create({
|
|
18480
|
+
...from.privilegedServices,
|
|
18481
|
+
assigners: asKnownSize([...from.privilegedServices.assigners]),
|
|
18482
|
+
});
|
|
18483
|
+
}
|
|
18484
|
+
return update;
|
|
18485
|
+
}
|
|
18484
18486
|
|
|
18485
|
-
/**
|
|
18486
|
-
|
|
18487
|
-
|
|
18488
|
-
|
|
18489
|
-
|
|
18490
|
-
|
|
18487
|
+
/** Retrieve and clear pending transfers. */
|
|
18488
|
+
takeTransfers() {
|
|
18489
|
+
const transfers = this.transfers;
|
|
18490
|
+
this.transfers = [];
|
|
18491
|
+
return transfers;
|
|
18492
|
+
}
|
|
18493
|
+
}
|
|
18491
18494
|
|
|
18492
|
-
|
|
18493
|
-
readonly currentServiceId: U32;
|
|
18495
|
+
type StateSlice = Pick<State, "getService" | "privilegedServices">;
|
|
18494
18496
|
|
|
18495
|
-
|
|
18496
|
-
|
|
18497
|
+
declare class PartiallyUpdatedState<T extends StateSlice = StateSlice> {
|
|
18498
|
+
/** A collection of state updates. */
|
|
18499
|
+
public readonly stateUpdate;
|
|
18500
|
+
|
|
18501
|
+
constructor(
|
|
18502
|
+
/** Original (unmodified state). */
|
|
18503
|
+
public readonly state: T,
|
|
18504
|
+
stateUpdate?: AccumulationStateUpdate,
|
|
18505
|
+
) {
|
|
18506
|
+
this.stateUpdate =
|
|
18507
|
+
stateUpdate === undefined ? AccumulationStateUpdate.empty() : AccumulationStateUpdate.copyFrom(stateUpdate);
|
|
18508
|
+
}
|
|
18497
18509
|
|
|
18498
18510
|
/**
|
|
18499
|
-
*
|
|
18511
|
+
* Retrieve info of service with given id.
|
|
18500
18512
|
*
|
|
18501
|
-
* NOTE the
|
|
18513
|
+
* NOTE the info may be updated compared to what is in the state.
|
|
18514
|
+
*
|
|
18515
|
+
* Takes into account ejected and newly created services as well.
|
|
18502
18516
|
*/
|
|
18503
|
-
|
|
18504
|
-
|
|
18517
|
+
getServiceInfo(destination: ServiceId | null): ServiceAccountInfo | null {
|
|
18518
|
+
if (destination === null) {
|
|
18519
|
+
return null;
|
|
18520
|
+
}
|
|
18505
18521
|
|
|
18506
|
-
|
|
18507
|
-
declare class HostCallsManager {
|
|
18508
|
-
private readonly hostCalls = new Map<HostCallIndex, HostCallHandler>();
|
|
18509
|
-
private readonly missing;
|
|
18522
|
+
const maybeUpdatedServiceInfo = this.stateUpdate.services.updated.get(destination);
|
|
18510
18523
|
|
|
18511
|
-
|
|
18512
|
-
|
|
18513
|
-
|
|
18514
|
-
}: {
|
|
18515
|
-
missing: HostCallHandler;
|
|
18516
|
-
handlers?: HostCallHandler[];
|
|
18517
|
-
}) {
|
|
18518
|
-
this.missing = missing;
|
|
18524
|
+
if (maybeUpdatedServiceInfo !== undefined) {
|
|
18525
|
+
return maybeUpdatedServiceInfo.action.account;
|
|
18526
|
+
}
|
|
18519
18527
|
|
|
18520
|
-
|
|
18521
|
-
|
|
18522
|
-
|
|
18528
|
+
const maybeService = this.state.getService(destination);
|
|
18529
|
+
if (maybeService === null) {
|
|
18530
|
+
return null;
|
|
18523
18531
|
}
|
|
18524
|
-
}
|
|
18525
18532
|
|
|
18526
|
-
|
|
18527
|
-
get(hostCallIndex: HostCallIndex): HostCallHandler {
|
|
18528
|
-
return this.hostCalls.get(hostCallIndex) ?? this.missing;
|
|
18533
|
+
return maybeService.getInfo();
|
|
18529
18534
|
}
|
|
18530
18535
|
|
|
18531
|
-
|
|
18532
|
-
|
|
18533
|
-
|
|
18534
|
-
|
|
18535
|
-
|
|
18536
|
-
|
|
18537
|
-
) {
|
|
18538
|
-
const { currentServiceId } = hostCallHandler;
|
|
18539
|
-
const requested = hostCallIndex !== hostCallHandler.index ? ` (${hostCallIndex})` : "";
|
|
18540
|
-
const name = `${hostCallHandler.constructor.name}:${hostCallHandler.index}`;
|
|
18541
|
-
const registerValues = hostCallHandler.tracedRegisters
|
|
18542
|
-
.map((idx) => [idx.toString().padStart(2, "0"), registers.get(idx)] as const)
|
|
18543
|
-
.filter((v) => v[1] !== 0n)
|
|
18544
|
-
.map(([idx, value]) => {
|
|
18545
|
-
return `r${idx}=${value} (0x${value.toString(16)})`;
|
|
18546
|
-
})
|
|
18547
|
-
.join(", ");
|
|
18548
|
-
logger.insane`[${currentServiceId}] ${context} ${name}${requested}. Gas: ${gas}. Regs: ${registerValues}.`;
|
|
18549
|
-
}
|
|
18550
|
-
}
|
|
18536
|
+
getStorage(serviceId: ServiceId, rawKey: StorageKey): BytesBlob | null {
|
|
18537
|
+
const storages = this.stateUpdate.services.storage.get(serviceId) ?? [];
|
|
18538
|
+
const item = storages.find((x) => x.key.isEqualTo(rawKey));
|
|
18539
|
+
if (item !== undefined) {
|
|
18540
|
+
return item.value;
|
|
18541
|
+
}
|
|
18551
18542
|
|
|
18552
|
-
|
|
18543
|
+
const service = this.state.getService(serviceId);
|
|
18544
|
+
return service?.getStorage(rawKey) ?? null;
|
|
18545
|
+
}
|
|
18553
18546
|
|
|
18554
|
-
|
|
18555
|
-
|
|
18556
|
-
|
|
18547
|
+
/**
|
|
18548
|
+
* Returns `true` if the preimage is already provided either in current
|
|
18549
|
+
* accumulation scope or earlier.
|
|
18550
|
+
*
|
|
18551
|
+
* NOTE: Does not check if the preimage is available, we just check
|
|
18552
|
+
* the existence in `preimages` map.
|
|
18553
|
+
*/
|
|
18554
|
+
hasPreimage(serviceId: ServiceId, hash: PreimageHash): boolean {
|
|
18555
|
+
const preimages = this.stateUpdate.services.preimages.get(serviceId) ?? [];
|
|
18556
|
+
const providedPreimage = preimages.find(
|
|
18557
|
+
// we ignore the action here, since if there is <any> update on that
|
|
18558
|
+
// hash it means it has to exist, right?
|
|
18559
|
+
(p) => p.hash.isEqualTo(hash),
|
|
18560
|
+
);
|
|
18561
|
+
if (providedPreimage !== undefined) {
|
|
18562
|
+
return true;
|
|
18563
|
+
}
|
|
18557
18564
|
|
|
18558
|
-
|
|
18559
|
-
|
|
18560
|
-
|
|
18561
|
-
|
|
18562
|
-
useSbrkGas: false,
|
|
18563
|
-
}),
|
|
18564
|
-
);
|
|
18565
|
+
// fallback to state preimages
|
|
18566
|
+
const service = this.state.getService(serviceId);
|
|
18567
|
+
if (service === undefined) {
|
|
18568
|
+
return false;
|
|
18565
18569
|
}
|
|
18570
|
+
|
|
18571
|
+
return service?.hasPreimage(hash) ?? false;
|
|
18566
18572
|
}
|
|
18567
18573
|
|
|
18568
|
-
|
|
18569
|
-
|
|
18570
|
-
|
|
18571
|
-
|
|
18574
|
+
getPreimage(serviceId: ServiceId, hash: PreimageHash): BytesBlob | null {
|
|
18575
|
+
// TODO [ToDr] Should we verify availability here?
|
|
18576
|
+
const preimages = this.stateUpdate.services.preimages.get(serviceId) ?? [];
|
|
18577
|
+
const freshlyProvided = preimages.find((x) => x.hash.isEqualTo(hash));
|
|
18578
|
+
if (freshlyProvided !== undefined && freshlyProvided.action.kind === UpdatePreimageKind.Provide) {
|
|
18579
|
+
return freshlyProvided.action.preimage.blob;
|
|
18572
18580
|
}
|
|
18573
|
-
|
|
18574
|
-
|
|
18575
|
-
|
|
18581
|
+
|
|
18582
|
+
const service = this.state.getService(serviceId);
|
|
18583
|
+
return service?.getPreimage(hash) ?? null;
|
|
18576
18584
|
}
|
|
18577
18585
|
|
|
18578
|
-
|
|
18579
|
-
|
|
18580
|
-
|
|
18581
|
-
|
|
18586
|
+
/** Get status of a preimage of current service taking into account any updates. */
|
|
18587
|
+
getLookupHistory(
|
|
18588
|
+
currentTimeslot: TimeSlot,
|
|
18589
|
+
serviceId: ServiceId,
|
|
18590
|
+
hash: PreimageHash,
|
|
18591
|
+
length: U64,
|
|
18592
|
+
): LookupHistoryItem | null {
|
|
18593
|
+
const preimages = this.stateUpdate.services.preimages.get(serviceId) ?? [];
|
|
18594
|
+
// TODO [ToDr] This is most likely wrong. We may have `provide` and `remove` within
|
|
18595
|
+
// the same state update. We should however switch to proper "updated state"
|
|
18596
|
+
// representation soon.
|
|
18597
|
+
const updatedPreimage = preimages.findLast(
|
|
18598
|
+
(update) => update.hash.isEqualTo(hash) && BigInt(update.length) === length,
|
|
18599
|
+
);
|
|
18600
|
+
|
|
18601
|
+
const stateFallback = () => {
|
|
18602
|
+
// fallback to state lookup
|
|
18603
|
+
const service = this.state.getService(serviceId);
|
|
18604
|
+
const lenU32 = preimageLenAsU32(length);
|
|
18605
|
+
if (lenU32 === null || service === null) {
|
|
18606
|
+
return null;
|
|
18607
|
+
}
|
|
18608
|
+
|
|
18609
|
+
const slots = service.getLookupHistory(hash, lenU32);
|
|
18610
|
+
return slots === null ? null : new LookupHistoryItem(hash, lenU32, slots);
|
|
18611
|
+
};
|
|
18612
|
+
|
|
18613
|
+
if (updatedPreimage === undefined) {
|
|
18614
|
+
return stateFallback();
|
|
18582
18615
|
}
|
|
18583
|
-
this.instances.push(pvm);
|
|
18584
|
-
}
|
|
18585
|
-
}
|
|
18586
18616
|
|
|
18587
|
-
|
|
18588
|
-
|
|
18589
|
-
|
|
18590
|
-
|
|
18591
|
-
|
|
18592
|
-
|
|
18593
|
-
|
|
18594
|
-
|
|
18595
|
-
|
|
18596
|
-
|
|
18597
|
-
|
|
18617
|
+
const { action } = updatedPreimage;
|
|
18618
|
+
switch (action.kind) {
|
|
18619
|
+
case UpdatePreimageKind.Provide: {
|
|
18620
|
+
// casting to U32 is safe, since we compare with object we have in memory.
|
|
18621
|
+
return new LookupHistoryItem(hash, updatedPreimage.length, tryAsLookupHistorySlots([currentTimeslot]));
|
|
18622
|
+
}
|
|
18623
|
+
case UpdatePreimageKind.Remove: {
|
|
18624
|
+
const state = stateFallback();
|
|
18625
|
+
// kinda impossible, since we know it's there because it's removed.
|
|
18626
|
+
if (state === null) {
|
|
18627
|
+
return null;
|
|
18628
|
+
}
|
|
18598
18629
|
|
|
18599
|
-
|
|
18600
|
-
|
|
18601
|
-
|
|
18630
|
+
return new LookupHistoryItem(hash, state.length, tryAsLookupHistorySlots([...state.slots, currentTimeslot]));
|
|
18631
|
+
}
|
|
18632
|
+
case UpdatePreimageKind.UpdateOrAdd: {
|
|
18633
|
+
return action.item;
|
|
18634
|
+
}
|
|
18635
|
+
}
|
|
18602
18636
|
|
|
18603
|
-
|
|
18604
|
-
return new ReturnValue(consumedGas, null, memorySlice);
|
|
18637
|
+
assertNever(action);
|
|
18605
18638
|
}
|
|
18606
18639
|
|
|
18607
|
-
|
|
18608
|
-
|
|
18609
|
-
|
|
18640
|
+
/* State update functions. */
|
|
18641
|
+
updateStorage(serviceId: ServiceId, key: StorageKey, value: BytesBlob | null) {
|
|
18642
|
+
const update =
|
|
18643
|
+
value === null
|
|
18644
|
+
? UpdateStorage.remove({ key })
|
|
18645
|
+
: UpdateStorage.set({
|
|
18646
|
+
storage: StorageItem.create({ key, value }),
|
|
18647
|
+
});
|
|
18610
18648
|
|
|
18611
|
-
|
|
18612
|
-
|
|
18649
|
+
const storages = this.stateUpdate.services.storage.get(serviceId) ?? [];
|
|
18650
|
+
const index = storages.findIndex((x) => x.key.isEqualTo(key));
|
|
18651
|
+
const count = index === -1 ? 0 : 1;
|
|
18652
|
+
storages.splice(index, count, update);
|
|
18653
|
+
this.stateUpdate.services.storage.set(serviceId, storages);
|
|
18613
18654
|
}
|
|
18614
|
-
}
|
|
18615
|
-
declare class HostCalls {
|
|
18616
|
-
constructor(
|
|
18617
|
-
private pvmInstanceManager: InterpreterInstanceManager,
|
|
18618
|
-
private hostCalls: HostCallsManager,
|
|
18619
|
-
) {}
|
|
18620
18655
|
|
|
18621
|
-
|
|
18622
|
-
|
|
18623
|
-
|
|
18624
|
-
|
|
18625
|
-
|
|
18656
|
+
/**
|
|
18657
|
+
* Update a preimage.
|
|
18658
|
+
*
|
|
18659
|
+
* Note we store all previous entries as well, since there might be a sequence of:
|
|
18660
|
+
* `provide` -> `remove` and both should update the end state somehow.
|
|
18661
|
+
*/
|
|
18662
|
+
updatePreimage(serviceId: ServiceId, newUpdate: UpdatePreimage) {
|
|
18663
|
+
const updatePreimages = this.stateUpdate.services.preimages.get(serviceId) ?? [];
|
|
18664
|
+
updatePreimages.push(newUpdate);
|
|
18665
|
+
this.stateUpdate.services.preimages.set(serviceId, updatePreimages);
|
|
18666
|
+
}
|
|
18626
18667
|
|
|
18627
|
-
|
|
18628
|
-
|
|
18629
|
-
|
|
18630
|
-
|
|
18631
|
-
|
|
18668
|
+
updateServiceStorageUtilisation(
|
|
18669
|
+
serviceId: ServiceId,
|
|
18670
|
+
items: number,
|
|
18671
|
+
bytes: bigint,
|
|
18672
|
+
serviceInfo: ServiceAccountInfo,
|
|
18673
|
+
): Result$2<OK, InsufficientFundsError> {
|
|
18674
|
+
check`${items >= 0} storageUtilisationCount has to be a positive number, got: ${items}`;
|
|
18675
|
+
check`${bytes >= 0} storageUtilisationBytes has to be a positive number, got: ${bytes}`;
|
|
18632
18676
|
|
|
18633
|
-
|
|
18634
|
-
|
|
18635
|
-
const loadResult = memory.loadInto(result, startAddress);
|
|
18677
|
+
const overflowItems = !isU32(items);
|
|
18678
|
+
const overflowBytes = !isU64(bytes);
|
|
18636
18679
|
|
|
18637
|
-
|
|
18638
|
-
|
|
18639
|
-
|
|
18680
|
+
// TODO [ToDr] this is not specified in GP, but it seems sensible.
|
|
18681
|
+
if (overflowItems || overflowBytes) {
|
|
18682
|
+
return Result.error(InsufficientFundsError);
|
|
18683
|
+
}
|
|
18640
18684
|
|
|
18641
|
-
|
|
18685
|
+
const thresholdBalance = ServiceAccountInfo.calculateThresholdBalance(items, bytes, serviceInfo.gratisStorage);
|
|
18686
|
+
if (serviceInfo.balance < thresholdBalance) {
|
|
18687
|
+
return Result.error(InsufficientFundsError);
|
|
18642
18688
|
}
|
|
18643
18689
|
|
|
18644
|
-
|
|
18690
|
+
// Update service info with new details.
|
|
18691
|
+
this.updateServiceInfo(
|
|
18692
|
+
serviceId,
|
|
18693
|
+
ServiceAccountInfo.create({
|
|
18694
|
+
...serviceInfo,
|
|
18695
|
+
storageUtilisationBytes: bytes,
|
|
18696
|
+
storageUtilisationCount: items,
|
|
18697
|
+
}),
|
|
18698
|
+
);
|
|
18699
|
+
return Result.ok(OK);
|
|
18645
18700
|
}
|
|
18646
18701
|
|
|
18647
|
-
|
|
18648
|
-
|
|
18649
|
-
for (;;) {
|
|
18650
|
-
let status = pvmInstance.getStatus();
|
|
18651
|
-
if (status !== Status.HOST) {
|
|
18652
|
-
return this.getReturnValue(status, pvmInstance);
|
|
18653
|
-
}
|
|
18654
|
-
check`
|
|
18655
|
-
${pvmInstance.getExitParam() !== null}
|
|
18656
|
-
"We know that the exit param is not null, because the status is 'Status.HOST'
|
|
18657
|
-
`;
|
|
18658
|
-
const hostCallIndex = pvmInstance.getExitParam() ?? -1;
|
|
18659
|
-
const gas = pvmInstance.getGasCounter();
|
|
18660
|
-
const regs = new HostCallRegisters(pvmInstance.getRegisters());
|
|
18661
|
-
const memory = new HostCallMemory(pvmInstance.getMemory());
|
|
18662
|
-
const index = tryAsHostCallIndex(hostCallIndex);
|
|
18663
|
-
|
|
18664
|
-
const hostCall = this.hostCalls.get(index);
|
|
18665
|
-
const gasBefore = gas.get();
|
|
18666
|
-
// NOTE: `basicGasCost(regs)` function is for compatibility reasons: pre GP 0.7.2
|
|
18667
|
-
const basicGasCost =
|
|
18668
|
-
typeof hostCall.basicGasCost === "number" ? hostCall.basicGasCost : hostCall.basicGasCost(regs);
|
|
18669
|
-
const underflow = gas.sub(basicGasCost);
|
|
18702
|
+
updateServiceInfo(serviceId: ServiceId, newInfo: ServiceAccountInfo) {
|
|
18703
|
+
const existingUpdate = this.stateUpdate.services.updated.get(serviceId);
|
|
18670
18704
|
|
|
18671
|
-
|
|
18672
|
-
|
|
18673
|
-
|
|
18674
|
-
|
|
18675
|
-
|
|
18676
|
-
|
|
18677
|
-
|
|
18678
|
-
this.hostCalls.traceHostCall(
|
|
18679
|
-
result === undefined ? `${pcLog} Result` : `${pcLog} Status(${PvmExecution[result]})`,
|
|
18680
|
-
index,
|
|
18681
|
-
hostCall,
|
|
18682
|
-
regs,
|
|
18683
|
-
gas.get(),
|
|
18705
|
+
if (existingUpdate?.action.kind === UpdateServiceKind.Create) {
|
|
18706
|
+
this.stateUpdate.services.updated.set(
|
|
18707
|
+
serviceId,
|
|
18708
|
+
UpdateService.create({
|
|
18709
|
+
serviceInfo: newInfo,
|
|
18710
|
+
lookupHistory: existingUpdate.action.lookupHistory,
|
|
18711
|
+
}),
|
|
18684
18712
|
);
|
|
18713
|
+
return;
|
|
18714
|
+
}
|
|
18685
18715
|
|
|
18686
|
-
|
|
18687
|
-
|
|
18688
|
-
|
|
18689
|
-
|
|
18690
|
-
|
|
18691
|
-
|
|
18692
|
-
|
|
18693
|
-
return this.getReturnValue(status, pvmInstance);
|
|
18694
|
-
}
|
|
18695
|
-
|
|
18696
|
-
if (result === PvmExecution.OOG) {
|
|
18697
|
-
status = Status.OOG;
|
|
18698
|
-
return this.getReturnValue(status, pvmInstance);
|
|
18699
|
-
}
|
|
18700
|
-
|
|
18701
|
-
if (result === undefined) {
|
|
18702
|
-
pvmInstance.runProgram();
|
|
18703
|
-
status = pvmInstance.getStatus();
|
|
18704
|
-
continue;
|
|
18705
|
-
}
|
|
18716
|
+
this.stateUpdate.services.updated.set(
|
|
18717
|
+
serviceId,
|
|
18718
|
+
UpdateService.update({
|
|
18719
|
+
serviceInfo: newInfo,
|
|
18720
|
+
}),
|
|
18721
|
+
);
|
|
18722
|
+
}
|
|
18706
18723
|
|
|
18707
|
-
|
|
18708
|
-
|
|
18724
|
+
createService(serviceId: ServiceId, newInfo: ServiceAccountInfo, newLookupHistory: LookupHistoryItem) {
|
|
18725
|
+
this.stateUpdate.services.created.push(serviceId);
|
|
18726
|
+
this.stateUpdate.services.updated.set(
|
|
18727
|
+
serviceId,
|
|
18728
|
+
UpdateService.create({
|
|
18729
|
+
serviceInfo: newInfo,
|
|
18730
|
+
lookupHistory: newLookupHistory,
|
|
18731
|
+
}),
|
|
18732
|
+
);
|
|
18709
18733
|
}
|
|
18710
18734
|
|
|
18711
|
-
|
|
18712
|
-
|
|
18713
|
-
|
|
18714
|
-
initialGas: Gas,
|
|
18715
|
-
maybeRegisters?: Registers,
|
|
18716
|
-
maybeMemory?: Memory,
|
|
18717
|
-
): Promise<ReturnValue> {
|
|
18718
|
-
const pvmInstance = await this.pvmInstanceManager.getInstance();
|
|
18719
|
-
pvmInstance.reset(rawProgram, initialPc, initialGas, maybeRegisters, maybeMemory);
|
|
18720
|
-
try {
|
|
18721
|
-
return await this.execute(pvmInstance);
|
|
18722
|
-
} finally {
|
|
18723
|
-
this.pvmInstanceManager.releaseInstance(pvmInstance);
|
|
18735
|
+
getPrivilegedServices() {
|
|
18736
|
+
if (this.stateUpdate.privilegedServices !== null) {
|
|
18737
|
+
return this.stateUpdate.privilegedServices;
|
|
18724
18738
|
}
|
|
18739
|
+
|
|
18740
|
+
return this.state.privilegedServices;
|
|
18725
18741
|
}
|
|
18726
18742
|
}
|
|
18727
18743
|
|
|
18728
|
-
|
|
18729
|
-
|
|
18730
|
-
|
|
18731
|
-
type index$7_HostCallRegisters = HostCallRegisters;
|
|
18732
|
-
declare const index$7_HostCallRegisters: typeof HostCallRegisters;
|
|
18733
|
-
type index$7_IHostCallMemory = IHostCallMemory;
|
|
18734
|
-
type index$7_IHostCallRegisters = IHostCallRegisters;
|
|
18735
|
-
type index$7_PvmExecution = PvmExecution;
|
|
18736
|
-
declare const index$7_PvmExecution: typeof PvmExecution;
|
|
18737
|
-
declare const index$7_traceRegisters: typeof traceRegisters;
|
|
18738
|
-
declare const index$7_tryAsHostCallIndex: typeof tryAsHostCallIndex;
|
|
18739
|
-
declare namespace index$7 {
|
|
18740
|
-
export { index$7_HostCallMemory as HostCallMemory, index$7_HostCallRegisters as HostCallRegisters, HostCallsManager as HostCalls, index$7_PvmExecution as PvmExecution, HostCalls as PvmHostCallExtension, InterpreterInstanceManager as PvmInstanceManager, index$7_traceRegisters as traceRegisters, index$7_tryAsHostCallIndex as tryAsHostCallIndex };
|
|
18741
|
-
export type { index$7_HostCallHandler as HostCallHandler, index$7_IHostCallMemory as IHostCallMemory, index$7_IHostCallRegisters as IHostCallRegisters };
|
|
18744
|
+
declare function preimageLenAsU32(length: U64) {
|
|
18745
|
+
// Safe to convert to Number and U32: we check that len < 2^32 before conversion
|
|
18746
|
+
return length >= 2n ** 32n ? null : tryAsU32(Number(length));
|
|
18742
18747
|
}
|
|
18743
18748
|
|
|
18749
|
+
/**
|
|
18750
|
+
* Host call result constants.
|
|
18751
|
+
*
|
|
18752
|
+
* https://graypaper.fluffylabs.dev/#/85129da/2c7c022c7c02?v=0.6.3
|
|
18753
|
+
*/
|
|
18754
|
+
declare const HostCallResult = {
|
|
18755
|
+
/** The return value indicating an item does not exist. */
|
|
18756
|
+
NONE: tryAsU64(0xffff_ffff_ffff_ffffn), // 2**64 - 1
|
|
18757
|
+
/** Name unknown. */
|
|
18758
|
+
WHAT: tryAsU64(0xffff_ffff_ffff_fffen), // 2**64 - 2
|
|
18759
|
+
/** The inner PVM memory index provided for reading/writing is not accessible. */
|
|
18760
|
+
OOB: tryAsU64(0xffff_ffff_ffff_fffdn), // 2**64 - 3
|
|
18761
|
+
/** Index unknown. */
|
|
18762
|
+
WHO: tryAsU64(0xffff_ffff_ffff_fffcn), // 2**64 - 4
|
|
18763
|
+
/** Storage full or resource already allocated. */
|
|
18764
|
+
FULL: tryAsU64(0xffff_ffff_ffff_fffbn), // 2**64 - 5
|
|
18765
|
+
/** Core index unknown. */
|
|
18766
|
+
CORE: tryAsU64(0xffff_ffff_ffff_fffan), // 2**64 - 6
|
|
18767
|
+
/** Insufficient funds. */
|
|
18768
|
+
CASH: tryAsU64(0xffff_ffff_ffff_fff9n), // 2**64 - 7
|
|
18769
|
+
/** Gas limit too low. */
|
|
18770
|
+
LOW: tryAsU64(0xffff_ffff_ffff_fff8n), // 2**64 - 8
|
|
18771
|
+
/** The item is already solicited, cannot be forgotten or the operation is invalid due to privilege level. */
|
|
18772
|
+
HUH: tryAsU64(0xffff_ffff_ffff_fff7n), // 2**64 - 9
|
|
18773
|
+
/** The return value indicating general success. */
|
|
18774
|
+
OK: tryAsU64(0n),
|
|
18775
|
+
} as const;
|
|
18776
|
+
|
|
18744
18777
|
declare const MAX_U32 = tryAsU32(2 ** 32 - 1);
|
|
18745
18778
|
declare const MAX_U32_BIG_INT = tryAsU64(MAX_U32);
|
|
18746
18779
|
declare const SERVICE_ID_BYTES = 4;
|
|
@@ -18831,6 +18864,7 @@ declare const index$6_UpdatePrivilegesError: typeof UpdatePrivilegesError;
|
|
|
18831
18864
|
type index$6_ZeroVoidError = ZeroVoidError;
|
|
18832
18865
|
declare const index$6_ZeroVoidError: typeof ZeroVoidError;
|
|
18833
18866
|
declare const index$6_clampU64ToU32: typeof clampU64ToU32;
|
|
18867
|
+
declare const index$6_deepCloneMapWithArray: typeof deepCloneMapWithArray;
|
|
18834
18868
|
declare const index$6_getServiceId: typeof getServiceId;
|
|
18835
18869
|
declare const index$6_getServiceIdOrCurrent: typeof getServiceIdOrCurrent;
|
|
18836
18870
|
declare const index$6_preimageLenAsU32: typeof preimageLenAsU32;
|
|
@@ -18840,7 +18874,7 @@ declare const index$6_tryAsMachineId: typeof tryAsMachineId;
|
|
|
18840
18874
|
declare const index$6_tryAsProgramCounter: typeof tryAsProgramCounter;
|
|
18841
18875
|
declare const index$6_writeServiceIdAsLeBytes: typeof writeServiceIdAsLeBytes;
|
|
18842
18876
|
declare namespace index$6 {
|
|
18843
|
-
export { index$6_AccumulationStateUpdate as AccumulationStateUpdate, index$6_CURRENT_SERVICE_ID as CURRENT_SERVICE_ID, index$6_EjectError as EjectError, index$6_ForgetPreimageError as ForgetPreimageError, index$6_HostCallResult as HostCallResult, index$6_MAX_U32 as MAX_U32, index$6_MAX_U32_BIG_INT as MAX_U32_BIG_INT, index$6_MachineInstance as MachineInstance, index$6_MemoryOperation as MemoryOperation, index$6_NewServiceError as NewServiceError, index$6_PagesError as PagesError, index$6_PartiallyUpdatedState as PartiallyUpdatedState, index$6_PeekPokeError as PeekPokeError, index$6_PendingTransfer as PendingTransfer, index$6_PreimageStatusKind as PreimageStatusKind, index$6_ProvidePreimageError as ProvidePreimageError, index$6_RequestPreimageError as RequestPreimageError, index$6_SERVICE_ID_BYTES as SERVICE_ID_BYTES, index$6_TransferError as TransferError, index$6_UpdatePrivilegesError as UpdatePrivilegesError, index$6_ZeroVoidError as ZeroVoidError, index$6_clampU64ToU32 as clampU64ToU32, index$6_getServiceId as getServiceId, index$6_getServiceIdOrCurrent as getServiceIdOrCurrent, index$6_preimageLenAsU32 as preimageLenAsU32, index$6_slotsToPreimageStatus as slotsToPreimageStatus, index$6_toMemoryOperation as toMemoryOperation, index$6_tryAsMachineId as tryAsMachineId, index$6_tryAsProgramCounter as tryAsProgramCounter, index$6_writeServiceIdAsLeBytes as writeServiceIdAsLeBytes };
|
|
18877
|
+
export { index$6_AccumulationStateUpdate as AccumulationStateUpdate, index$6_CURRENT_SERVICE_ID as CURRENT_SERVICE_ID, index$6_EjectError as EjectError, index$6_ForgetPreimageError as ForgetPreimageError, index$6_HostCallResult as HostCallResult, index$6_MAX_U32 as MAX_U32, index$6_MAX_U32_BIG_INT as MAX_U32_BIG_INT, index$6_MachineInstance as MachineInstance, index$6_MemoryOperation as MemoryOperation, index$6_NewServiceError as NewServiceError, index$6_PagesError as PagesError, index$6_PartiallyUpdatedState as PartiallyUpdatedState, index$6_PeekPokeError as PeekPokeError, index$6_PendingTransfer as PendingTransfer, index$6_PreimageStatusKind as PreimageStatusKind, index$6_ProvidePreimageError as ProvidePreimageError, index$6_RequestPreimageError as RequestPreimageError, index$6_SERVICE_ID_BYTES as SERVICE_ID_BYTES, index$6_TransferError as TransferError, index$6_UpdatePrivilegesError as UpdatePrivilegesError, index$6_ZeroVoidError as ZeroVoidError, index$6_clampU64ToU32 as clampU64ToU32, index$6_deepCloneMapWithArray as deepCloneMapWithArray, index$6_getServiceId as getServiceId, index$6_getServiceIdOrCurrent as getServiceIdOrCurrent, index$6_preimageLenAsU32 as preimageLenAsU32, index$6_slotsToPreimageStatus as slotsToPreimageStatus, index$6_toMemoryOperation as toMemoryOperation, index$6_tryAsMachineId as tryAsMachineId, index$6_tryAsProgramCounter as tryAsProgramCounter, index$6_writeServiceIdAsLeBytes as writeServiceIdAsLeBytes };
|
|
18844
18878
|
export type { index$6_InsufficientFundsError as InsufficientFundsError, index$6_MachineId as MachineId, index$6_MachineResult as MachineResult, index$6_MachineStatus as MachineStatus, index$6_NoMachineError as NoMachineError, index$6_PartialState as PartialState, index$6_PreimageStatus as PreimageStatus, index$6_ProgramCounter as ProgramCounter, index$6_RefineExternalities as RefineExternalities, index$6_SegmentExportError as SegmentExportError, index$6_ServiceStateUpdate as ServiceStateUpdate, index$6_StateSlice as StateSlice, index$6_TRANSFER_MEMO_BYTES as TRANSFER_MEMO_BYTES, index$6_UnprivilegedError as UnprivilegedError };
|
|
18845
18879
|
}
|
|
18846
18880
|
|
|
@@ -19241,6 +19275,7 @@ declare const index$3_check: typeof check;
|
|
|
19241
19275
|
declare const index$3_clampU64ToU32: typeof clampU64ToU32;
|
|
19242
19276
|
declare const index$3_createResults: typeof createResults;
|
|
19243
19277
|
declare const index$3_decodeStandardProgram: typeof decodeStandardProgram;
|
|
19278
|
+
declare const index$3_deepCloneMapWithArray: typeof deepCloneMapWithArray;
|
|
19244
19279
|
declare const index$3_extractCodeAndMetadata: typeof extractCodeAndMetadata;
|
|
19245
19280
|
declare const index$3_getServiceId: typeof getServiceId;
|
|
19246
19281
|
declare const index$3_getServiceIdOrCurrent: typeof getServiceIdOrCurrent;
|
|
@@ -19259,7 +19294,7 @@ declare const index$3_tryAsMachineId: typeof tryAsMachineId;
|
|
|
19259
19294
|
declare const index$3_tryAsProgramCounter: typeof tryAsProgramCounter;
|
|
19260
19295
|
declare const index$3_writeServiceIdAsLeBytes: typeof writeServiceIdAsLeBytes;
|
|
19261
19296
|
declare namespace index$3 {
|
|
19262
|
-
export { index$3_AccumulationStateUpdate as AccumulationStateUpdate, index$3_ArgsDecoder as ArgsDecoder, index$3_ArgumentType as ArgumentType, index$3_BasicBlocks as BasicBlocks, index$3_CURRENT_SERVICE_ID as CURRENT_SERVICE_ID, index$3_EjectError as EjectError, index$3_ExtendedWitdthImmediateDecoder as ExtendedWitdthImmediateDecoder, index$3_ForgetPreimageError as ForgetPreimageError, index$3_HostCallMemory as HostCallMemory, index$3_HostCallRegisters as HostCallRegisters, index$3_HostCallResult as HostCallResult, index$3_ImmediateDecoder as ImmediateDecoder, index$3_MAX_U32 as MAX_U32, index$3_MAX_U32_BIG_INT as MAX_U32_BIG_INT, index$3_MachineInstance as MachineInstance, index$3_Mask as Mask, index$3_MemoryOperation as MemoryOperation, index$3_MemorySegment as MemorySegment, NO_OF_REGISTERS$1 as NO_OF_REGISTERS, index$3_NewServiceError as NewServiceError, index$3_NibblesDecoder as NibblesDecoder, index$3_PagesError as PagesError, index$3_PartiallyUpdatedState as PartiallyUpdatedState, index$3_PeekPokeError as PeekPokeError, index$3_PendingTransfer as PendingTransfer, index$3_PreimageStatusKind as PreimageStatusKind, index$3_Program as Program, index$3_ProgramDecoder as ProgramDecoder, index$3_ProvidePreimageError as ProvidePreimageError, DebuggerAdapter as Pvm, index$3_Registers as Registers, index$3_RequestPreimageError as RequestPreimageError, Result$2 as Result, index$3_RichTaggedError as RichTaggedError, index$3_SERVICE_ID_BYTES as SERVICE_ID_BYTES, index$3_SpiMemory as SpiMemory, index$3_SpiProgram as SpiProgram, index$3_TransferError as TransferError, index$3_UpdatePrivilegesError as UpdatePrivilegesError, index$3_WithDebug as WithDebug, index$3_ZeroVoidError as ZeroVoidError, index$3___OPAQUE_TYPE__ as __OPAQUE_TYPE__, index$3_asOpaqueType as asOpaqueType, index$3_assertEmpty as assertEmpty, index$3_assertNever as assertNever, index$l as block, index$s as bytes, index$3_check as check, index$3_clampU64ToU32 as clampU64ToU32, index$3_createResults as createResults, index$3_decodeStandardProgram as decodeStandardProgram, index$3_extractCodeAndMetadata as extractCodeAndMetadata, index$3_getServiceId as getServiceId, index$3_getServiceIdOrCurrent as getServiceIdOrCurrent, index$p as hash, index$3_inspect as inspect, index$3_instructionArgumentTypeMap as instructionArgumentTypeMap, index$8 as interpreter, index$3_isBrowser as isBrowser, index$3_isTaggedError as isTaggedError, index$3_maybeTaggedErrorToString as maybeTaggedErrorToString, index$3_measure as measure, index$r as numbers, index$3_preimageLenAsU32 as preimageLenAsU32, index$3_resultToString as resultToString, index$3_seeThrough as seeThrough, index$3_slotsToPreimageStatus as slotsToPreimageStatus, index$3_toMemoryOperation as toMemoryOperation, index$3_tryAsMachineId as tryAsMachineId, index$3_tryAsProgramCounter as tryAsProgramCounter, index$3_writeServiceIdAsLeBytes as writeServiceIdAsLeBytes };
|
|
19297
|
+
export { index$3_AccumulationStateUpdate as AccumulationStateUpdate, index$3_ArgsDecoder as ArgsDecoder, index$3_ArgumentType as ArgumentType, index$3_BasicBlocks as BasicBlocks, index$3_CURRENT_SERVICE_ID as CURRENT_SERVICE_ID, index$3_EjectError as EjectError, index$3_ExtendedWitdthImmediateDecoder as ExtendedWitdthImmediateDecoder, index$3_ForgetPreimageError as ForgetPreimageError, index$3_HostCallMemory as HostCallMemory, index$3_HostCallRegisters as HostCallRegisters, index$3_HostCallResult as HostCallResult, index$3_ImmediateDecoder as ImmediateDecoder, index$3_MAX_U32 as MAX_U32, index$3_MAX_U32_BIG_INT as MAX_U32_BIG_INT, index$3_MachineInstance as MachineInstance, index$3_Mask as Mask, index$3_MemoryOperation as MemoryOperation, index$3_MemorySegment as MemorySegment, NO_OF_REGISTERS$1 as NO_OF_REGISTERS, index$3_NewServiceError as NewServiceError, index$3_NibblesDecoder as NibblesDecoder, index$3_PagesError as PagesError, index$3_PartiallyUpdatedState as PartiallyUpdatedState, index$3_PeekPokeError as PeekPokeError, index$3_PendingTransfer as PendingTransfer, index$3_PreimageStatusKind as PreimageStatusKind, index$3_Program as Program, index$3_ProgramDecoder as ProgramDecoder, index$3_ProvidePreimageError as ProvidePreimageError, DebuggerAdapter as Pvm, index$3_Registers as Registers, index$3_RequestPreimageError as RequestPreimageError, Result$2 as Result, index$3_RichTaggedError as RichTaggedError, index$3_SERVICE_ID_BYTES as SERVICE_ID_BYTES, index$3_SpiMemory as SpiMemory, index$3_SpiProgram as SpiProgram, index$3_TransferError as TransferError, index$3_UpdatePrivilegesError as UpdatePrivilegesError, index$3_WithDebug as WithDebug, index$3_ZeroVoidError as ZeroVoidError, index$3___OPAQUE_TYPE__ as __OPAQUE_TYPE__, index$3_asOpaqueType as asOpaqueType, index$3_assertEmpty as assertEmpty, index$3_assertNever as assertNever, index$l as block, index$s as bytes, index$3_check as check, index$3_clampU64ToU32 as clampU64ToU32, index$3_createResults as createResults, index$3_decodeStandardProgram as decodeStandardProgram, index$3_deepCloneMapWithArray as deepCloneMapWithArray, index$3_extractCodeAndMetadata as extractCodeAndMetadata, index$3_getServiceId as getServiceId, index$3_getServiceIdOrCurrent as getServiceIdOrCurrent, index$p as hash, index$3_inspect as inspect, index$3_instructionArgumentTypeMap as instructionArgumentTypeMap, index$8 as interpreter, index$3_isBrowser as isBrowser, index$3_isTaggedError as isTaggedError, index$3_maybeTaggedErrorToString as maybeTaggedErrorToString, index$3_measure as measure, index$r as numbers, index$3_preimageLenAsU32 as preimageLenAsU32, index$3_resultToString as resultToString, index$3_seeThrough as seeThrough, index$3_slotsToPreimageStatus as slotsToPreimageStatus, index$3_toMemoryOperation as toMemoryOperation, index$3_tryAsMachineId as tryAsMachineId, index$3_tryAsProgramCounter as tryAsProgramCounter, index$3_writeServiceIdAsLeBytes as writeServiceIdAsLeBytes };
|
|
19263
19298
|
export type { index$3_Args as Args, index$3_EnumMapping as EnumMapping, index$3_ErrorResult as ErrorResult, index$3_IHostCallMemory as IHostCallMemory, index$3_IHostCallRegisters as IHostCallRegisters, index$3_InsufficientFundsError as InsufficientFundsError, index$3_MachineId as MachineId, index$3_MachineResult as MachineResult, index$3_MachineStatus as MachineStatus, index$3_NoMachineError as NoMachineError, index$3_OK as OK, index$3_OkResult as OkResult, index$3_Opaque as Opaque, index$3_PartialState as PartialState, index$3_PreimageStatus as PreimageStatus, index$3_ProgramCounter as ProgramCounter, index$3_RefineExternalities as RefineExternalities, index$3_SegmentExportError as SegmentExportError, index$3_ServiceStateUpdate as ServiceStateUpdate, index$3_StateSlice as StateSlice, index$3_StringLiteral as StringLiteral, index$3_TRANSFER_MEMO_BYTES as TRANSFER_MEMO_BYTES, index$3_TaggedError as TaggedError, index$3_TokenOf as TokenOf, index$3_Uninstantiable as Uninstantiable, index$3_UnprivilegedError as UnprivilegedError, index$3_WithOpaque as WithOpaque };
|
|
19264
19299
|
}
|
|
19265
19300
|
|
|
@@ -20094,7 +20129,7 @@ declare class Preimages {
|
|
|
20094
20129
|
}
|
|
20095
20130
|
|
|
20096
20131
|
const { preimages, slot } = input;
|
|
20097
|
-
const pendingChanges
|
|
20132
|
+
const pendingChanges = new Map<ServiceId, UpdatePreimage[]>();
|
|
20098
20133
|
|
|
20099
20134
|
// select preimages for integration
|
|
20100
20135
|
for (const preimage of preimages) {
|
|
@@ -20115,13 +20150,14 @@ declare class Preimages {
|
|
|
20115
20150
|
}
|
|
20116
20151
|
|
|
20117
20152
|
// https://graypaper.fluffylabs.dev/#/5f542d7/18c00018f300
|
|
20118
|
-
pendingChanges.
|
|
20153
|
+
const updates = pendingChanges.get(requester) ?? [];
|
|
20154
|
+
updates.push(
|
|
20119
20155
|
UpdatePreimage.provide({
|
|
20120
|
-
serviceId: requester,
|
|
20121
20156
|
preimage: PreimageItem.create({ hash, blob }),
|
|
20122
20157
|
slot,
|
|
20123
20158
|
}),
|
|
20124
20159
|
);
|
|
20160
|
+
pendingChanges.set(requester, updates);
|
|
20125
20161
|
}
|
|
20126
20162
|
|
|
20127
20163
|
return Result.ok({
|