@typeberry/convert 0.2.0-5746fdc → 0.2.0-79dc2d4
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/README.md +3 -3
- package/index.js +261 -145
- package/index.js.map +1 -1
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -4245,44 +4245,40 @@ var compatibility_GpVersion;
|
|
|
4245
4245
|
GpVersion["V0_6_7"] = "0.6.7";
|
|
4246
4246
|
GpVersion["V0_7_0"] = "0.7.0";
|
|
4247
4247
|
GpVersion["V0_7_1"] = "0.7.1";
|
|
4248
|
-
GpVersion["V0_7_2"] = "0.7.2
|
|
4248
|
+
GpVersion["V0_7_2"] = "0.7.2";
|
|
4249
4249
|
})(compatibility_GpVersion || (compatibility_GpVersion = {}));
|
|
4250
|
-
var
|
|
4250
|
+
var compatibility_TestSuite;
|
|
4251
4251
|
(function (TestSuite) {
|
|
4252
4252
|
TestSuite["W3F_DAVXY"] = "w3f-davxy";
|
|
4253
4253
|
TestSuite["JAMDUNA"] = "jamduna";
|
|
4254
|
-
})(
|
|
4255
|
-
const
|
|
4256
|
-
const
|
|
4254
|
+
})(compatibility_TestSuite || (compatibility_TestSuite = {}));
|
|
4255
|
+
const ALL_VERSIONS_IN_ORDER = [compatibility_GpVersion.V0_6_7, compatibility_GpVersion.V0_7_0, compatibility_GpVersion.V0_7_1, compatibility_GpVersion.V0_7_2];
|
|
4256
|
+
const DEFAULT_SUITE = compatibility_TestSuite.W3F_DAVXY;
|
|
4257
|
+
const DEFAULT_VERSION = compatibility_GpVersion.V0_7_2;
|
|
4257
4258
|
const env = typeof process === "undefined" ? {} : process.env;
|
|
4258
4259
|
let CURRENT_VERSION = parseCurrentVersion(env.GP_VERSION) ?? DEFAULT_VERSION;
|
|
4259
4260
|
let CURRENT_SUITE = parseCurrentSuite(env.TEST_SUITE) ?? DEFAULT_SUITE;
|
|
4260
|
-
const ALL_VERSIONS_IN_ORDER = [compatibility_GpVersion.V0_6_7, compatibility_GpVersion.V0_7_0, compatibility_GpVersion.V0_7_1, compatibility_GpVersion.V0_7_2];
|
|
4261
4261
|
function parseCurrentVersion(env) {
|
|
4262
4262
|
if (env === undefined) {
|
|
4263
4263
|
return undefined;
|
|
4264
4264
|
}
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
case compatibility_GpVersion.V0_7_2:
|
|
4270
|
-
return env;
|
|
4271
|
-
default:
|
|
4272
|
-
throw new Error(`Configured environment variable GP_VERSION is unknown: '${env}'. Use one of: ${ALL_VERSIONS_IN_ORDER}`);
|
|
4265
|
+
for (const v of Object.values(compatibility_GpVersion)) {
|
|
4266
|
+
if (env === v) {
|
|
4267
|
+
return v;
|
|
4268
|
+
}
|
|
4273
4269
|
}
|
|
4270
|
+
throw new Error(`Configured environment variable GP_VERSION is unknown: '${env}'. Use one of: ${ALL_VERSIONS_IN_ORDER}`);
|
|
4274
4271
|
}
|
|
4275
4272
|
function parseCurrentSuite(env) {
|
|
4276
4273
|
if (env === undefined) {
|
|
4277
4274
|
return undefined;
|
|
4278
4275
|
}
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
default:
|
|
4284
|
-
throw new Error(`Configured environment variable TEST_SUITE is unknown: '${env}'. Use one of: ${Object.values(TestSuite)}`);
|
|
4276
|
+
for (const s of Object.values(compatibility_TestSuite)) {
|
|
4277
|
+
if (env === s) {
|
|
4278
|
+
return s;
|
|
4279
|
+
}
|
|
4285
4280
|
}
|
|
4281
|
+
throw new Error(`Configured environment variable TEST_SUITE is unknown: '${env}'. Use one of: ${Object.values(compatibility_TestSuite)}`);
|
|
4286
4282
|
}
|
|
4287
4283
|
class compatibility_Compatibility {
|
|
4288
4284
|
static override(version) {
|
|
@@ -4443,6 +4439,13 @@ class WithDebug {
|
|
|
4443
4439
|
return debug_inspect(this);
|
|
4444
4440
|
}
|
|
4445
4441
|
}
|
|
4442
|
+
function lazyInspect(obj) {
|
|
4443
|
+
return {
|
|
4444
|
+
toString() {
|
|
4445
|
+
return debug_inspect(obj);
|
|
4446
|
+
},
|
|
4447
|
+
};
|
|
4448
|
+
}
|
|
4446
4449
|
|
|
4447
4450
|
;// CONCATENATED MODULE: ./packages/core/utils/dev.ts
|
|
4448
4451
|
const dev_env = typeof process === "undefined" ? {} : process.env;
|
|
@@ -5227,7 +5230,7 @@ const asTypedNumber = (v) => v;
|
|
|
5227
5230
|
const MAX_VALUE_U8 = 0xff;
|
|
5228
5231
|
const MAX_VALUE_U16 = 0xffff;
|
|
5229
5232
|
const MAX_VALUE_U32 = 0xffff_ffff;
|
|
5230
|
-
const
|
|
5233
|
+
const numbers_MAX_VALUE_U64 = 0xffffffffffffffffn;
|
|
5231
5234
|
/** Attempt to cast an input number into U8. */
|
|
5232
5235
|
const tryAsU8 = (v) => {
|
|
5233
5236
|
debug_check `${isU8(v)} input must have one-byte representation, got ${v}`;
|
|
@@ -5256,7 +5259,7 @@ const numbers_tryAsU64 = (x) => {
|
|
|
5256
5259
|
return asTypedNumber(v);
|
|
5257
5260
|
};
|
|
5258
5261
|
/** Check if given number is a valid U64 number. */
|
|
5259
|
-
const numbers_isU64 = (v) => (v &
|
|
5262
|
+
const numbers_isU64 = (v) => (v & numbers_MAX_VALUE_U64) === v;
|
|
5260
5263
|
/** Collate two U32 parts into one U64. */
|
|
5261
5264
|
const u64FromParts = ({ lower, upper }) => {
|
|
5262
5265
|
const val = (BigInt(upper) << 32n) + BigInt(lower);
|
|
@@ -10785,7 +10788,7 @@ const DEV_CONFIG = "dev";
|
|
|
10785
10788
|
const DEFAULT_CONFIG = "default";
|
|
10786
10789
|
const NODE_DEFAULTS = {
|
|
10787
10790
|
name: isBrowser() ? "browser" : external_node_os_default().hostname(),
|
|
10788
|
-
config: DEFAULT_CONFIG,
|
|
10791
|
+
config: [DEFAULT_CONFIG],
|
|
10789
10792
|
pvm: pvm_backend_PvmBackend.BuiltIn,
|
|
10790
10793
|
};
|
|
10791
10794
|
/** Chain spec chooser. */
|
|
@@ -10838,25 +10841,137 @@ class NodeConfiguration {
|
|
|
10838
10841
|
this.authorship = authorship;
|
|
10839
10842
|
}
|
|
10840
10843
|
}
|
|
10841
|
-
function loadConfig(
|
|
10842
|
-
|
|
10843
|
-
|
|
10844
|
-
|
|
10845
|
-
|
|
10846
|
-
|
|
10847
|
-
|
|
10848
|
-
|
|
10844
|
+
function loadConfig(config, withRelPath) {
|
|
10845
|
+
node_config_logger.log `🔧 Loading config`;
|
|
10846
|
+
let mergedJson = {};
|
|
10847
|
+
for (const entry of config) {
|
|
10848
|
+
node_config_logger.log `🔧 Applying '${entry}'`;
|
|
10849
|
+
if (entry === DEV_CONFIG) {
|
|
10850
|
+
mergedJson = structuredClone(configs.dev); // clone to avoid mutating the original config. not doing a merge since dev and default should theoretically replace all properties.
|
|
10851
|
+
continue;
|
|
10852
|
+
}
|
|
10853
|
+
if (entry === DEFAULT_CONFIG) {
|
|
10854
|
+
mergedJson = structuredClone(configs.default);
|
|
10855
|
+
continue;
|
|
10856
|
+
}
|
|
10857
|
+
// try to parse as JSON
|
|
10858
|
+
try {
|
|
10859
|
+
const parsed = JSON.parse(entry);
|
|
10860
|
+
deepMerge(mergedJson, parsed);
|
|
10861
|
+
continue;
|
|
10862
|
+
}
|
|
10863
|
+
catch { }
|
|
10864
|
+
// if not, try to load as file
|
|
10865
|
+
if (entry.indexOf("=") === -1 && entry.endsWith(".json")) {
|
|
10866
|
+
try {
|
|
10867
|
+
const configFile = fs.readFileSync(withRelPath(entry), "utf8");
|
|
10868
|
+
const parsed = JSON.parse(configFile);
|
|
10869
|
+
deepMerge(mergedJson, parsed);
|
|
10870
|
+
}
|
|
10871
|
+
catch (e) {
|
|
10872
|
+
throw new Error(`Unable to load config from ${entry}: ${e}`);
|
|
10873
|
+
}
|
|
10874
|
+
}
|
|
10875
|
+
else {
|
|
10876
|
+
// finally try to process as a pseudo-jq query
|
|
10877
|
+
try {
|
|
10878
|
+
processQuery(mergedJson, entry, withRelPath);
|
|
10879
|
+
}
|
|
10880
|
+
catch (e) {
|
|
10881
|
+
throw new Error(`Error while processing '${entry}': ${e}`);
|
|
10882
|
+
}
|
|
10883
|
+
}
|
|
10849
10884
|
}
|
|
10850
10885
|
try {
|
|
10851
|
-
|
|
10852
|
-
|
|
10853
|
-
|
|
10854
|
-
return parseFromJson(parsed, NodeConfiguration.fromJson);
|
|
10886
|
+
const parsed = parseFromJson(mergedJson, NodeConfiguration.fromJson);
|
|
10887
|
+
node_config_logger.log `🔧 Config ready`;
|
|
10888
|
+
return parsed;
|
|
10855
10889
|
}
|
|
10856
10890
|
catch (e) {
|
|
10857
|
-
throw new Error(`Unable to
|
|
10891
|
+
throw new Error(`Unable to parse config: ${e}`);
|
|
10858
10892
|
}
|
|
10859
10893
|
}
|
|
10894
|
+
function deepMerge(target, source) {
|
|
10895
|
+
if (!isJsonObject(source)) {
|
|
10896
|
+
throw new Error(`Expected object, got ${source}`);
|
|
10897
|
+
}
|
|
10898
|
+
for (const key in source) {
|
|
10899
|
+
if (isJsonObject(source[key])) {
|
|
10900
|
+
if (!isJsonObject(target[key])) {
|
|
10901
|
+
target[key] = {};
|
|
10902
|
+
}
|
|
10903
|
+
deepMerge(target[key], source[key]);
|
|
10904
|
+
}
|
|
10905
|
+
else {
|
|
10906
|
+
target[key] = source[key];
|
|
10907
|
+
}
|
|
10908
|
+
}
|
|
10909
|
+
}
|
|
10910
|
+
/**
|
|
10911
|
+
* Caution: updates input directly.
|
|
10912
|
+
* Processes a pseudo-jq query. Syntax:
|
|
10913
|
+
* .path.to.value = { ... } - updates value with the specified object by replacement
|
|
10914
|
+
* .path.to.value += { ... } - updates value with the specified object by merging
|
|
10915
|
+
* .path.to.value = file.json - updates value with the contents of file.json
|
|
10916
|
+
* .path.to.value += file.json - merges the contents of file.json onto value
|
|
10917
|
+
*/
|
|
10918
|
+
function processQuery(input, query, withRelPath) {
|
|
10919
|
+
const queryParts = query.split("=");
|
|
10920
|
+
if (queryParts.length === 2) {
|
|
10921
|
+
let [path, value] = queryParts.map((part) => part.trim());
|
|
10922
|
+
let merge = false;
|
|
10923
|
+
// detect += syntax
|
|
10924
|
+
if (path.endsWith("+")) {
|
|
10925
|
+
merge = true;
|
|
10926
|
+
path = path.slice(0, -1);
|
|
10927
|
+
}
|
|
10928
|
+
let parsedValue;
|
|
10929
|
+
if (value.endsWith(".json")) {
|
|
10930
|
+
try {
|
|
10931
|
+
const configFile = fs.readFileSync(withRelPath(value), "utf8");
|
|
10932
|
+
const parsed = JSON.parse(configFile);
|
|
10933
|
+
parsedValue = parsed;
|
|
10934
|
+
}
|
|
10935
|
+
catch (e) {
|
|
10936
|
+
throw new Error(`Unable to load config from ${value}: ${e}`);
|
|
10937
|
+
}
|
|
10938
|
+
}
|
|
10939
|
+
else {
|
|
10940
|
+
try {
|
|
10941
|
+
parsedValue = JSON.parse(value);
|
|
10942
|
+
}
|
|
10943
|
+
catch (e) {
|
|
10944
|
+
throw new Error(`Unrecognized syntax '${value}': ${e}`);
|
|
10945
|
+
}
|
|
10946
|
+
}
|
|
10947
|
+
let pathParts = path.split(".");
|
|
10948
|
+
// allow leading dot in path
|
|
10949
|
+
if (pathParts[0] === "") {
|
|
10950
|
+
pathParts = pathParts.slice(1);
|
|
10951
|
+
}
|
|
10952
|
+
let target = input;
|
|
10953
|
+
for (let i = 0; i < pathParts.length; i++) {
|
|
10954
|
+
const part = pathParts[i];
|
|
10955
|
+
if (!isJsonObject(target[part])) {
|
|
10956
|
+
target[part] = {};
|
|
10957
|
+
}
|
|
10958
|
+
if (i === pathParts.length - 1) {
|
|
10959
|
+
if (merge) {
|
|
10960
|
+
deepMerge(target[part], parsedValue);
|
|
10961
|
+
}
|
|
10962
|
+
else {
|
|
10963
|
+
target[part] = parsedValue;
|
|
10964
|
+
}
|
|
10965
|
+
return;
|
|
10966
|
+
}
|
|
10967
|
+
target = target[part];
|
|
10968
|
+
}
|
|
10969
|
+
}
|
|
10970
|
+
throw new Error("Unrecognized syntax.");
|
|
10971
|
+
}
|
|
10972
|
+
function isJsonObject(value) {
|
|
10973
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10974
|
+
}
|
|
10860
10975
|
|
|
10861
10976
|
;// CONCATENATED MODULE: ./packages/jam/config-node/index.ts
|
|
10862
10977
|
|
|
@@ -12144,7 +12259,7 @@ class service_LookupHistoryItem {
|
|
|
12144
12259
|
|
|
12145
12260
|
|
|
12146
12261
|
|
|
12147
|
-
const codecServiceId = compatibility_Compatibility.isSuite(
|
|
12262
|
+
const codecServiceId = compatibility_Compatibility.isSuite(compatibility_TestSuite.W3F_DAVXY) || compatibility_Compatibility.isSuite(compatibility_TestSuite.JAMDUNA, compatibility_GpVersion.V0_6_7)
|
|
12148
12263
|
? descriptors_codec.u32.asOpaque()
|
|
12149
12264
|
: descriptors_codec.varU32.convert((s) => numbers_tryAsU32(s), (i) => common_tryAsServiceId(i));
|
|
12150
12265
|
/**
|
|
@@ -12483,26 +12598,6 @@ class InMemoryStateView {
|
|
|
12483
12598
|
|
|
12484
12599
|
|
|
12485
12600
|
|
|
12486
|
-
/** Dictionary entry of services that auto-accumulate every block. */
|
|
12487
|
-
class privileged_services_AutoAccumulate {
|
|
12488
|
-
service;
|
|
12489
|
-
gasLimit;
|
|
12490
|
-
static Codec = descriptors_codec.Class(privileged_services_AutoAccumulate, {
|
|
12491
|
-
service: descriptors_codec.u32.asOpaque(),
|
|
12492
|
-
gasLimit: descriptors_codec.u64.asOpaque(),
|
|
12493
|
-
});
|
|
12494
|
-
static create({ service, gasLimit }) {
|
|
12495
|
-
return new privileged_services_AutoAccumulate(service, gasLimit);
|
|
12496
|
-
}
|
|
12497
|
-
constructor(
|
|
12498
|
-
/** Service id that auto-accumulates. */
|
|
12499
|
-
service,
|
|
12500
|
-
/** Gas limit for auto-accumulation. */
|
|
12501
|
-
gasLimit) {
|
|
12502
|
-
this.service = service;
|
|
12503
|
-
this.gasLimit = gasLimit;
|
|
12504
|
-
}
|
|
12505
|
-
}
|
|
12506
12601
|
/**
|
|
12507
12602
|
* https://graypaper.fluffylabs.dev/#/ab2cdbd/114402114402?v=0.7.2
|
|
12508
12603
|
*/
|
|
@@ -12520,7 +12615,9 @@ class privileged_services_PrivilegedServices {
|
|
|
12520
12615
|
registrar: compatibility_Compatibility.isGreaterOrEqual(compatibility_GpVersion.V0_7_1)
|
|
12521
12616
|
? descriptors_codec.u32.asOpaque()
|
|
12522
12617
|
: ignoreValueWithDefault(common_tryAsServiceId(2 ** 32 - 1)),
|
|
12523
|
-
autoAccumulateServices:
|
|
12618
|
+
autoAccumulateServices: descriptors_codec.dictionary(descriptors_codec.u32.asOpaque(), descriptors_codec.u64.asOpaque(), {
|
|
12619
|
+
sortKeys: (a, b) => a - b,
|
|
12620
|
+
}),
|
|
12524
12621
|
});
|
|
12525
12622
|
static create(a) {
|
|
12526
12623
|
return new privileged_services_PrivilegedServices(a.manager, a.delegator, a.registrar, a.assigners, a.autoAccumulateServices);
|
|
@@ -13153,7 +13250,7 @@ class in_memory_state_InMemoryState extends WithDebug {
|
|
|
13153
13250
|
assigners: common_tryAsPerCore(new Array(spec.coresCount).fill(common_tryAsServiceId(0)), spec),
|
|
13154
13251
|
delegator: common_tryAsServiceId(0),
|
|
13155
13252
|
registrar: common_tryAsServiceId(math_consts_MAX_VALUE),
|
|
13156
|
-
autoAccumulateServices:
|
|
13253
|
+
autoAccumulateServices: new Map(),
|
|
13157
13254
|
}),
|
|
13158
13255
|
accumulationOutputLog: sorted_array_SortedArray.fromArray(accumulation_output_accumulationOutputComparator, []),
|
|
13159
13256
|
services: new Map(),
|
|
@@ -13625,10 +13722,7 @@ const fullStateDumpFromJson = (spec) => json.object({
|
|
|
13625
13722
|
chi_a: json.array("number"),
|
|
13626
13723
|
chi_v: "number",
|
|
13627
13724
|
chi_r: json.optional("number"),
|
|
13628
|
-
chi_g: json.nullable(json.
|
|
13629
|
-
service: "number",
|
|
13630
|
-
gasLimit: json.fromNumber((v) => common_tryAsServiceGas(v)),
|
|
13631
|
-
})),
|
|
13725
|
+
chi_g: json.nullable(json.map("number", json.fromNumber((v) => common_tryAsServiceGas(v)))),
|
|
13632
13726
|
},
|
|
13633
13727
|
pi: JsonStatisticsData.fromJson,
|
|
13634
13728
|
omega: json.array(json.array(notYetAccumulatedFromJson)),
|
|
@@ -13669,7 +13763,7 @@ const fullStateDumpFromJson = (spec) => json.object({
|
|
|
13669
13763
|
assigners: chi.chi_a,
|
|
13670
13764
|
delegator: chi.chi_v,
|
|
13671
13765
|
registrar: chi.chi_r ?? common_tryAsServiceId(2 ** 32 - 1),
|
|
13672
|
-
autoAccumulateServices: chi.chi_g ??
|
|
13766
|
+
autoAccumulateServices: chi.chi_g ?? new Map(),
|
|
13673
13767
|
}),
|
|
13674
13768
|
statistics: JsonStatisticsData.toStatisticsData(spec, pi),
|
|
13675
13769
|
accumulationQueue: omega,
|
|
@@ -17700,7 +17794,7 @@ class accumulate_externalities_AccumulateExternalities {
|
|
|
17700
17794
|
updatedState;
|
|
17701
17795
|
currentServiceId;
|
|
17702
17796
|
currentTimeslot;
|
|
17703
|
-
checkpointedState
|
|
17797
|
+
checkpointedState;
|
|
17704
17798
|
/** `x_i`: next service id we are going to create. */
|
|
17705
17799
|
nextNewServiceId;
|
|
17706
17800
|
constructor(chainSpec, blake2b, updatedState,
|
|
@@ -17711,13 +17805,14 @@ class accumulate_externalities_AccumulateExternalities {
|
|
|
17711
17805
|
this.updatedState = updatedState;
|
|
17712
17806
|
this.currentServiceId = currentServiceId;
|
|
17713
17807
|
this.currentTimeslot = currentTimeslot;
|
|
17808
|
+
this.checkpointedState = AccumulationStateUpdate.copyFrom(updatedState.stateUpdate);
|
|
17714
17809
|
this.nextNewServiceId = this.getNextAvailableServiceId(nextNewServiceIdCandidate);
|
|
17715
17810
|
const service = this.updatedState.getServiceInfo(this.currentServiceId);
|
|
17716
17811
|
if (service === null) {
|
|
17717
17812
|
throw new Error(`Invalid state initialization. Service info missing for ${this.currentServiceId}.`);
|
|
17718
17813
|
}
|
|
17719
17814
|
}
|
|
17720
|
-
/** Return the underlying state update and checkpointed state
|
|
17815
|
+
/** Return the underlying state update and checkpointed state. */
|
|
17721
17816
|
getStateUpdates() {
|
|
17722
17817
|
return [this.updatedState.stateUpdate, this.checkpointedState];
|
|
17723
17818
|
}
|
|
@@ -18084,7 +18179,7 @@ class accumulate_externalities_AccumulateExternalities {
|
|
|
18084
18179
|
assigners: authorizers,
|
|
18085
18180
|
delegator: delegator,
|
|
18086
18181
|
registrar: registrar ?? tryAsServiceId(0),
|
|
18087
|
-
autoAccumulateServices: autoAccumulate
|
|
18182
|
+
autoAccumulateServices: autoAccumulate,
|
|
18088
18183
|
});
|
|
18089
18184
|
return Result.ok(OK);
|
|
18090
18185
|
}
|
|
@@ -18108,9 +18203,7 @@ class accumulate_externalities_AccumulateExternalities {
|
|
|
18108
18203
|
isAlreadyChanged: currentAssigner !== original.assigners[index],
|
|
18109
18204
|
}));
|
|
18110
18205
|
const newManager = isManager ? manager : current.manager;
|
|
18111
|
-
const newAutoAccumulateServices = isManager
|
|
18112
|
-
? autoAccumulate.map(([service, gasLimit]) => AutoAccumulate.create({ service, gasLimit }))
|
|
18113
|
-
: current.autoAccumulateServices;
|
|
18206
|
+
const newAutoAccumulateServices = isManager ? autoAccumulate : current.autoAccumulateServices;
|
|
18114
18207
|
// finally update the privileges
|
|
18115
18208
|
this.updatedState.stateUpdate.privilegedServices = PrivilegedServices.create({
|
|
18116
18209
|
manager: newManager,
|
|
@@ -18254,7 +18347,7 @@ function bumpServiceId(serviceId) {
|
|
|
18254
18347
|
*/
|
|
18255
18348
|
class operand_Operand extends WithDebug {
|
|
18256
18349
|
// JamDuna uses a different order of operands.
|
|
18257
|
-
static Codec = descriptors_codec.Class(operand_Operand, compatibility_Compatibility.isSuite(
|
|
18350
|
+
static Codec = descriptors_codec.Class(operand_Operand, compatibility_Compatibility.isSuite(compatibility_TestSuite.JAMDUNA)
|
|
18258
18351
|
? {
|
|
18259
18352
|
hash: descriptors_codec.bytes(hash_HASH_SIZE).asOpaque(),
|
|
18260
18353
|
exportsRoot: descriptors_codec.bytes(hash_HASH_SIZE).asOpaque(),
|
|
@@ -18738,17 +18831,16 @@ class fetch_externalities_FetchExternalities {
|
|
|
18738
18831
|
|
|
18739
18832
|
|
|
18740
18833
|
|
|
18834
|
+
|
|
18741
18835
|
class AccumulateDataItem {
|
|
18742
18836
|
operands;
|
|
18743
18837
|
reportsLength;
|
|
18744
|
-
|
|
18745
|
-
constructor(operands, reportsLength, gasCost) {
|
|
18838
|
+
constructor(operands, reportsLength) {
|
|
18746
18839
|
this.operands = operands;
|
|
18747
18840
|
this.reportsLength = reportsLength;
|
|
18748
|
-
this.gasCost = gasCost;
|
|
18749
18841
|
}
|
|
18750
18842
|
static empty() {
|
|
18751
|
-
return new AccumulateDataItem([], tryAsU32(0)
|
|
18843
|
+
return new AccumulateDataItem([], tryAsU32(0));
|
|
18752
18844
|
}
|
|
18753
18845
|
}
|
|
18754
18846
|
/**
|
|
@@ -18758,23 +18850,43 @@ class AccumulateDataItem {
|
|
|
18758
18850
|
* - gas cost and reports length for each service (statistics)
|
|
18759
18851
|
*/
|
|
18760
18852
|
class accumulate_data_AccumulateData {
|
|
18853
|
+
autoAccumulateServicesByServiceId;
|
|
18761
18854
|
reportsDataByServiceId;
|
|
18762
18855
|
transfersByServiceId;
|
|
18763
|
-
autoAccumulateServicesByServiceId;
|
|
18764
18856
|
serviceIds;
|
|
18765
|
-
|
|
18766
|
-
|
|
18857
|
+
gasLimitByServiceId;
|
|
18858
|
+
constructor(reports, transfers, autoAccumulateServicesByServiceId) {
|
|
18767
18859
|
this.autoAccumulateServicesByServiceId = autoAccumulateServicesByServiceId;
|
|
18768
|
-
const
|
|
18860
|
+
const serviceIdsFromAutoAccumulate = new Set(autoAccumulateServicesByServiceId.keys());
|
|
18861
|
+
const { reportsDataByServiceId, serviceIds: serviceIdsFromReports, gasLimitByServiceId: reportsGasLimitByServiceId, } = this.transformReports(reports);
|
|
18769
18862
|
this.reportsDataByServiceId = reportsDataByServiceId;
|
|
18770
|
-
const { transfersByServiceId, serviceIds: serviceIdsFromTransfers } = this.transformTransfers(transfers);
|
|
18863
|
+
const { transfersByServiceId, serviceIds: serviceIdsFromTransfers, gasLimitByServiceId: transfersGasLimitByServiceId, } = this.transformTransfers(transfers);
|
|
18771
18864
|
this.transfersByServiceId = transfersByServiceId;
|
|
18772
18865
|
/**
|
|
18773
18866
|
* Merge service ids from reports, auto-accumulate services and transfers.
|
|
18774
18867
|
*
|
|
18775
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
18868
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/173803174b03?v=0.7.2
|
|
18776
18869
|
*/
|
|
18777
18870
|
this.serviceIds = this.mergeServiceIds(serviceIdsFromReports, serviceIdsFromAutoAccumulate, serviceIdsFromTransfers);
|
|
18871
|
+
/**
|
|
18872
|
+
* Merge gas limits from reports, auto-accumulate services and transfers.
|
|
18873
|
+
*
|
|
18874
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/182001183701?v=0.7.2
|
|
18875
|
+
*/
|
|
18876
|
+
this.gasLimitByServiceId = this.mergeGasLimitByServiceId(this.serviceIds, autoAccumulateServicesByServiceId, reportsGasLimitByServiceId, transfersGasLimitByServiceId);
|
|
18877
|
+
}
|
|
18878
|
+
/**
|
|
18879
|
+
* Calculate the gas limit implied by the selected deferred-transfers, work-reports and gas-privileges.
|
|
18880
|
+
*
|
|
18881
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/182001183701?v=0.7.2
|
|
18882
|
+
*/
|
|
18883
|
+
mergeGasLimitByServiceId(serviceIds, ...gasLimitByServiceIdMaps) {
|
|
18884
|
+
const gasByServiceId = new Map();
|
|
18885
|
+
for (const serviceId of serviceIds) {
|
|
18886
|
+
const { overflow, value } = sumU64(...gasLimitByServiceIdMaps.map((map) => map.get(serviceId) ?? tryAsServiceGas(0)));
|
|
18887
|
+
gasByServiceId.set(serviceId, tryAsServiceGas(overflow ? MAX_VALUE_U64 : value));
|
|
18888
|
+
}
|
|
18889
|
+
return gasByServiceId;
|
|
18778
18890
|
}
|
|
18779
18891
|
/** Merge two sets of service ids */
|
|
18780
18892
|
mergeServiceIds(...sources) {
|
|
@@ -18786,50 +18898,60 @@ class accumulate_data_AccumulateData {
|
|
|
18786
18898
|
}
|
|
18787
18899
|
return Array.from(merged);
|
|
18788
18900
|
}
|
|
18901
|
+
/**
|
|
18902
|
+
* Transform the list of pending transfers into:
|
|
18903
|
+
* - map: transfers by service id
|
|
18904
|
+
* - map: gas limit by service id
|
|
18905
|
+
* - set: service ids
|
|
18906
|
+
*/
|
|
18789
18907
|
transformTransfers(transfersToTransform) {
|
|
18790
18908
|
const transfersByServiceId = new Map();
|
|
18791
18909
|
const serviceIds = new Set();
|
|
18910
|
+
const gasLimitByServiceId = new Map();
|
|
18792
18911
|
for (const transfer of transfersToTransform) {
|
|
18793
18912
|
const serviceId = transfer.destination;
|
|
18794
18913
|
const transfers = transfersByServiceId.get(serviceId) ?? [];
|
|
18914
|
+
const gas = gasLimitByServiceId.get(serviceId) ?? tryAsServiceGas(0n);
|
|
18915
|
+
const { value, overflow } = sumU64(gas, transfer.gas);
|
|
18916
|
+
gasLimitByServiceId.set(serviceId, tryAsServiceGas(overflow ? MAX_VALUE_U64 : value));
|
|
18795
18917
|
transfers.push(transfer);
|
|
18796
18918
|
transfersByServiceId.set(serviceId, transfers);
|
|
18797
18919
|
serviceIds.add(serviceId);
|
|
18798
18920
|
}
|
|
18799
|
-
return { transfersByServiceId, serviceIds };
|
|
18800
|
-
}
|
|
18801
|
-
/** Transform the list of auto-accumulate services into a map by service id. */
|
|
18802
|
-
transformAutoAccumulateServices(autoAccumulateServices) {
|
|
18803
|
-
const serviceIds = new Set();
|
|
18804
|
-
const autoAccumulateServicesByServiceId = new Map();
|
|
18805
|
-
for (const autoAccumulate of autoAccumulateServices) {
|
|
18806
|
-
autoAccumulateServicesByServiceId.set(autoAccumulate.service, autoAccumulate);
|
|
18807
|
-
serviceIds.add(autoAccumulate.service);
|
|
18808
|
-
}
|
|
18809
|
-
return { autoAccumulateServicesByServiceId, serviceIds };
|
|
18921
|
+
return { transfersByServiceId, serviceIds, gasLimitByServiceId };
|
|
18810
18922
|
}
|
|
18811
18923
|
/**
|
|
18812
18924
|
* A function that transform reports into a list of operands and data needed for statistics (gas cost and reports length).
|
|
18813
18925
|
*/
|
|
18926
|
+
/**
|
|
18927
|
+
* Transform the list of reports into:
|
|
18928
|
+
* - map: AccumulateDataItem by service id
|
|
18929
|
+
* - map: gas limit by service id
|
|
18930
|
+
* - set: service ids
|
|
18931
|
+
*/
|
|
18814
18932
|
transformReports(reports) {
|
|
18815
18933
|
const reportsDataByServiceId = new Map();
|
|
18934
|
+
const gasLimitByServiceId = new Map();
|
|
18816
18935
|
const serviceIds = new Set();
|
|
18817
18936
|
for (const report of reports) {
|
|
18818
18937
|
for (const result of report.results) {
|
|
18819
18938
|
const serviceId = result.serviceId;
|
|
18820
18939
|
serviceIds.add(serviceId);
|
|
18821
18940
|
const item = reportsDataByServiceId.get(serviceId) ?? AccumulateDataItem.empty();
|
|
18941
|
+
const gas = gasLimitByServiceId.get(serviceId) ?? tryAsServiceGas(0n);
|
|
18942
|
+
const { value, overflow } = sumU64(gas, result.gas);
|
|
18943
|
+
const newGas = tryAsServiceGas(overflow ? MAX_VALUE_U64 : value);
|
|
18944
|
+
gasLimitByServiceId.set(serviceId, newGas);
|
|
18822
18945
|
/**
|
|
18823
18946
|
* We count the report results and gas cost for each service to update service statistics.
|
|
18824
18947
|
*
|
|
18825
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
18948
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/180504182604?v=0.7.2
|
|
18826
18949
|
*/
|
|
18827
18950
|
item.reportsLength = tryAsU32(item.reportsLength + 1);
|
|
18828
|
-
item.gasCost = tryAsServiceGas(item.gasCost + result.gas);
|
|
18829
18951
|
/**
|
|
18830
18952
|
* Transform report into an operand
|
|
18831
18953
|
*
|
|
18832
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
18954
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/185901181402?v=0.7.2
|
|
18833
18955
|
*/
|
|
18834
18956
|
item.operands.push(Operand.new({
|
|
18835
18957
|
gas: result.gas, // g
|
|
@@ -18843,19 +18965,7 @@ class accumulate_data_AccumulateData {
|
|
|
18843
18965
|
reportsDataByServiceId.set(serviceId, item);
|
|
18844
18966
|
}
|
|
18845
18967
|
}
|
|
18846
|
-
|
|
18847
|
-
* Add initial gas cost - it is `U(f_s, 0)` from this formula:
|
|
18848
|
-
*
|
|
18849
|
-
* https://graypaper.fluffylabs.dev/#/68eaa1f/17b00217b002?v=0.6.4
|
|
18850
|
-
*/
|
|
18851
|
-
for (const serviceId of serviceIds) {
|
|
18852
|
-
const item = reportsDataByServiceId.get(serviceId) ?? null;
|
|
18853
|
-
const autoAccumulateService = this.autoAccumulateServicesByServiceId.get(serviceId) ?? null;
|
|
18854
|
-
if (item !== null && autoAccumulateService !== null) {
|
|
18855
|
-
item.gasCost = tryAsServiceGas(item.gasCost + autoAccumulateService.gasLimit);
|
|
18856
|
-
}
|
|
18857
|
-
}
|
|
18858
|
-
return { reportsDataByServiceId, serviceIds };
|
|
18968
|
+
return { reportsDataByServiceId, serviceIds, gasLimitByServiceId };
|
|
18859
18969
|
}
|
|
18860
18970
|
/** Returns the list of operands for a given service id */
|
|
18861
18971
|
getOperands(serviceId) {
|
|
@@ -18869,14 +18979,14 @@ class accumulate_data_AccumulateData {
|
|
|
18869
18979
|
getReportsLength(serviceId) {
|
|
18870
18980
|
return this.reportsDataByServiceId.get(serviceId)?.reportsLength ?? tryAsU32(0);
|
|
18871
18981
|
}
|
|
18872
|
-
/** Returns the gas
|
|
18873
|
-
|
|
18874
|
-
return this.
|
|
18982
|
+
/** Returns the gas limit for a given service id */
|
|
18983
|
+
getGasLimit(serviceId) {
|
|
18984
|
+
return this.gasLimitByServiceId.get(serviceId) ?? tryAsServiceGas(0n);
|
|
18875
18985
|
}
|
|
18876
18986
|
/**
|
|
18877
18987
|
* Returns a list of service ids that should be accumulated.
|
|
18878
18988
|
*
|
|
18879
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
18989
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/173803174a03?v=0.7.2
|
|
18880
18990
|
*/
|
|
18881
18991
|
getServiceIds() {
|
|
18882
18992
|
return this.serviceIds;
|
|
@@ -23252,7 +23362,7 @@ class Bless {
|
|
|
23252
23362
|
* `z`: array of key-value pairs serviceId -> gas that auto-accumulate every block
|
|
23253
23363
|
* https://graypaper.fluffylabs.dev/#/7e6ff6a/368100368100?v=0.6.7
|
|
23254
23364
|
*/
|
|
23255
|
-
const
|
|
23365
|
+
const autoAccumulate = new Map();
|
|
23256
23366
|
const result = safe_alloc_uint8array_safeAllocUint8Array(tryAsExactBytes(serviceIdAndGasCodec.sizeHint));
|
|
23257
23367
|
const decoder = decoder_Decoder.fromBlob(result);
|
|
23258
23368
|
let memIndex = sourceStart;
|
|
@@ -23265,7 +23375,7 @@ class Bless {
|
|
|
23265
23375
|
return host_call_handler_PvmExecution.Panic;
|
|
23266
23376
|
}
|
|
23267
23377
|
const { serviceId, gas } = decoder.object(serviceIdAndGasCodec);
|
|
23268
|
-
|
|
23378
|
+
autoAccumulate.set(serviceId, gas);
|
|
23269
23379
|
// we allow the index to go beyond `MEMORY_SIZE` (i.e. 2**32) and have the next `loadInto` fail with page fault.
|
|
23270
23380
|
memIndex = numbers_tryAsU64(memIndex + numbers_tryAsU64(decoder.bytesRead()));
|
|
23271
23381
|
}
|
|
@@ -23274,26 +23384,26 @@ class Bless {
|
|
|
23274
23384
|
const authorizersDecoder = decoder_Decoder.fromBlob(res);
|
|
23275
23385
|
const memoryReadResult = memory.loadInto(res, authorization);
|
|
23276
23386
|
if (memoryReadResult.isError) {
|
|
23277
|
-
logger_logger.trace `BLESS(${manager}, ${delegator}, ${registrar}, ${
|
|
23387
|
+
logger_logger.trace `BLESS(${manager}, ${delegator}, ${registrar}, ${lazyInspect(autoAccumulate)}) <- PANIC`;
|
|
23278
23388
|
return host_call_handler_PvmExecution.Panic;
|
|
23279
23389
|
}
|
|
23280
23390
|
// `a`
|
|
23281
23391
|
const authorizers = common_tryAsPerCore(authorizersDecoder.sequenceFixLen(descriptors_codec.u32.asOpaque(), this.chainSpec.coresCount), this.chainSpec);
|
|
23282
|
-
const updateResult = this.partialState.updatePrivilegedServices(manager, authorizers, delegator, registrar,
|
|
23392
|
+
const updateResult = this.partialState.updatePrivilegedServices(manager, authorizers, delegator, registrar, autoAccumulate);
|
|
23283
23393
|
if (updateResult.isOk) {
|
|
23284
|
-
logger_logger.trace `BLESS(${manager}, ${authorizers}, ${delegator}, ${registrar}, ${
|
|
23394
|
+
logger_logger.trace `BLESS(${manager}, ${authorizers}, ${delegator}, ${registrar}, ${lazyInspect(autoAccumulate)}) <- OK`;
|
|
23285
23395
|
regs.set(bless_IN_OUT_REG, results_HostCallResult.OK);
|
|
23286
23396
|
return;
|
|
23287
23397
|
}
|
|
23288
23398
|
const e = updateResult.error;
|
|
23289
23399
|
// NOTE: `UpdatePrivilegesError.UnprivilegedService` won't happen in 0.7.1+
|
|
23290
23400
|
if (e === partial_state_UpdatePrivilegesError.UnprivilegedService) {
|
|
23291
|
-
logger_logger.trace `BLESS(${manager}, ${authorizers}, ${delegator}, ${registrar}, ${
|
|
23401
|
+
logger_logger.trace `BLESS(${manager}, ${authorizers}, ${delegator}, ${registrar}, ${lazyInspect(autoAccumulate)}) <- HUH`;
|
|
23292
23402
|
regs.set(bless_IN_OUT_REG, results_HostCallResult.HUH);
|
|
23293
23403
|
return;
|
|
23294
23404
|
}
|
|
23295
23405
|
if (e === partial_state_UpdatePrivilegesError.InvalidServiceId) {
|
|
23296
|
-
logger_logger.trace `BLESS(${manager}, ${authorizers}, ${delegator}, ${registrar}, ${
|
|
23406
|
+
logger_logger.trace `BLESS(${manager}, ${authorizers}, ${delegator}, ${registrar}, ${lazyInspect(autoAccumulate)}) <- WHO`;
|
|
23297
23407
|
regs.set(bless_IN_OUT_REG, results_HostCallResult.WHO);
|
|
23298
23408
|
return;
|
|
23299
23409
|
}
|
|
@@ -24117,8 +24227,8 @@ var FetchKind;
|
|
|
24117
24227
|
|
|
24118
24228
|
|
|
24119
24229
|
const info_IN_OUT_REG = 7;
|
|
24120
|
-
const OFFSET_REG = compatibility_Compatibility.isSuite(
|
|
24121
|
-
const LEN_REG = compatibility_Compatibility.isSuite(
|
|
24230
|
+
const OFFSET_REG = compatibility_Compatibility.isSuite(compatibility_TestSuite.W3F_DAVXY) || compatibility_Compatibility.isGreaterOrEqual(compatibility_GpVersion.V0_7_2) ? 9 : 11;
|
|
24231
|
+
const LEN_REG = compatibility_Compatibility.isSuite(compatibility_TestSuite.W3F_DAVXY) || compatibility_Compatibility.isGreaterOrEqual(compatibility_GpVersion.V0_7_2) ? 10 : 12;
|
|
24122
24232
|
/**
|
|
24123
24233
|
* Return info about some account.
|
|
24124
24234
|
*
|
|
@@ -24593,6 +24703,7 @@ class pvm_executor_PvmExecutor {
|
|
|
24593
24703
|
|
|
24594
24704
|
|
|
24595
24705
|
|
|
24706
|
+
|
|
24596
24707
|
const ACCUMULATION_ERROR = "duplicate service created";
|
|
24597
24708
|
var PvmInvocationError;
|
|
24598
24709
|
(function (PvmInvocationError) {
|
|
@@ -24761,7 +24872,7 @@ class accumulate_Accumulate {
|
|
|
24761
24872
|
const { gasCost, state: stateAfterParallelAcc, ...rest } = await this.accumulateInParallel(accumulateData, slot, entropy, statistics, stateUpdate);
|
|
24762
24873
|
assertEmpty(rest);
|
|
24763
24874
|
// NOTE [ToDr] recursive invocation
|
|
24764
|
-
const { accumulatedReports, gasCost: seqGasCost, state, ...seqRest } = await this.accumulateSequentiallyLegacy(tryAsServiceGas(gasLimit - gasCost), reportsToAccumulateSequentially, slot, entropy, statistics, stateAfterParallelAcc,
|
|
24875
|
+
const { accumulatedReports, gasCost: seqGasCost, state, ...seqRest } = await this.accumulateSequentiallyLegacy(tryAsServiceGas(gasLimit - gasCost), reportsToAccumulateSequentially, slot, entropy, statistics, stateAfterParallelAcc, new Map());
|
|
24765
24876
|
assertEmpty(seqRest);
|
|
24766
24877
|
return {
|
|
24767
24878
|
accumulatedReports: tryAsU32(i + accumulatedReports),
|
|
@@ -24793,8 +24904,15 @@ class accumulate_Accumulate {
|
|
|
24793
24904
|
const { gasCost, state: stateAfterParallelAcc, ...rest } = await this.accumulateInParallel(accumulateData, slot, entropy, statistics, stateUpdate);
|
|
24794
24905
|
const newTransfers = stateAfterParallelAcc.takeTransfers();
|
|
24795
24906
|
assertEmpty(rest);
|
|
24907
|
+
/**
|
|
24908
|
+
* Gas limit from transfers is added to the next round of accumulation
|
|
24909
|
+
*
|
|
24910
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/172b02172b02?v=0.7.2
|
|
24911
|
+
*/
|
|
24912
|
+
const transfersGas = transfers.map((t) => t.gas);
|
|
24913
|
+
const { value: newGasLimit, overflow } = sumU64(tryAsServiceGas(gasLimit - gasCost), ...transfersGas);
|
|
24796
24914
|
// NOTE [ToDr] recursive invocation
|
|
24797
|
-
const { accumulatedReports, gasCost: seqGasCost, state, ...seqRest } = await this.accumulateSequentially(tryAsServiceGas(
|
|
24915
|
+
const { accumulatedReports, gasCost: seqGasCost, state, ...seqRest } = await this.accumulateSequentially(tryAsServiceGas(overflow ? MAX_VALUE_U64 : newGasLimit), reportsToAccumulateSequentially, newTransfers, slot, entropy, statistics, stateAfterParallelAcc, new Map());
|
|
24798
24916
|
assertEmpty(seqRest);
|
|
24799
24917
|
return {
|
|
24800
24918
|
accumulatedReports: tryAsU32(i + accumulatedReports),
|
|
@@ -24820,14 +24938,16 @@ class accumulate_Accumulate {
|
|
|
24820
24938
|
for (const serviceId of serviceIds) {
|
|
24821
24939
|
const checkpoint = AccumulationStateUpdate.copyFrom(currentState);
|
|
24822
24940
|
const operands = accumulateData.getOperands(serviceId);
|
|
24823
|
-
const { consumedGas, stateUpdate } = await this.accumulateSingleService(serviceId, accumulateData.getTransfers(serviceId), operands, accumulateData.
|
|
24941
|
+
const { consumedGas, stateUpdate } = await this.accumulateSingleService(serviceId, accumulateData.getTransfers(serviceId), operands, accumulateData.getGasLimit(serviceId), slot, entropy, currentState);
|
|
24824
24942
|
gasCost = tryAsServiceGas(gasCost + consumedGas);
|
|
24825
24943
|
// https://graypaper.fluffylabs.dev/#/ab2cdbd/193b05193b05?v=0.7.2
|
|
24826
24944
|
const serviceStatistics = statistics.get(serviceId) ?? { count: tryAsU32(0), gasUsed: tryAsServiceGas(0) };
|
|
24827
24945
|
const count = accumulateData.getReportsLength(serviceId);
|
|
24828
24946
|
// [0.7.1]: do not update statistics, if the service only had incoming transfers
|
|
24829
24947
|
if ((Compatibility.isLessThan(GpVersion.V0_7_2) && count > 0) ||
|
|
24830
|
-
(Compatibility.isGreaterOrEqual(GpVersion.V0_7_2)
|
|
24948
|
+
((Compatibility.isGreaterOrEqual(GpVersion.V0_7_2) ||
|
|
24949
|
+
(Compatibility.isSuite(TestSuite.W3F_DAVXY) && Compatibility.is(GpVersion.V0_7_1))) &&
|
|
24950
|
+
(count > 0 || consumedGas > 0n))) {
|
|
24831
24951
|
serviceStatistics.count = tryAsU32(serviceStatistics.count + count);
|
|
24832
24952
|
serviceStatistics.gasUsed = tryAsServiceGas(serviceStatistics.gasUsed + consumedGas);
|
|
24833
24953
|
statistics.set(serviceId, serviceStatistics);
|
|
@@ -24840,7 +24960,7 @@ class accumulate_Accumulate {
|
|
|
24840
24960
|
// Since serviceIds already contains newV, this service gets accumulated twice.
|
|
24841
24961
|
// To avoid double-counting, we skip stats and gas cost tracking here.
|
|
24842
24962
|
// We need this accumulation to get the correct `delegator`
|
|
24843
|
-
const { stateUpdate } = await this.accumulateSingleService(newV, [], accumulateData.getOperands(newV), accumulateData.
|
|
24963
|
+
const { stateUpdate } = await this.accumulateSingleService(newV, [], accumulateData.getOperands(newV), accumulateData.getGasLimit(newV), slot, entropy, checkpoint);
|
|
24844
24964
|
const correctV = stateUpdate?.privilegedServices?.delegator ?? this.state.privilegedServices.delegator;
|
|
24845
24965
|
currentState.privilegedServices = PrivilegedServices.create({
|
|
24846
24966
|
...currentState.privilegedServices,
|
|
@@ -24906,7 +25026,7 @@ class accumulate_Accumulate {
|
|
|
24906
25026
|
*/
|
|
24907
25027
|
getGasLimit() {
|
|
24908
25028
|
const calculatedGasLimit = GAS_TO_INVOKE_WORK_REPORT * BigInt(this.chainSpec.coresCount) +
|
|
24909
|
-
this.state.privilegedServices.autoAccumulateServices.reduce((acc,
|
|
25029
|
+
Array.from(this.state.privilegedServices.autoAccumulateServices.values()).reduce((acc, gasLimit) => acc + gasLimit, 0n);
|
|
24910
25030
|
const gasLimit = tryAsServiceGas(this.chainSpec.maxBlockGas > calculatedGasLimit ? this.chainSpec.maxBlockGas : calculatedGasLimit);
|
|
24911
25031
|
return tryAsServiceGas(gasLimit);
|
|
24912
25032
|
}
|
|
@@ -25059,9 +25179,8 @@ class deferred_transfers_DeferredTransfers {
|
|
|
25059
25179
|
consumedGas = (await executor.run(args, tryAsGas(gas))).consumedGas;
|
|
25060
25180
|
}
|
|
25061
25181
|
transferStatistics.set(serviceId, { count: tryAsU32(transfers.length), gasUsed: tryAsServiceGas(consumedGas) });
|
|
25062
|
-
const [updatedState
|
|
25182
|
+
const [updatedState] = partialState.getStateUpdates();
|
|
25063
25183
|
currentStateUpdate = updatedState;
|
|
25064
|
-
check `${checkpointedState === null} On transfer cannot invoke checkpoint.`;
|
|
25065
25184
|
}
|
|
25066
25185
|
return Result.ok({
|
|
25067
25186
|
// NOTE: we return only services, since it's impossible to update
|
|
@@ -26378,7 +26497,6 @@ class statistics_Statistics {
|
|
|
26378
26497
|
|
|
26379
26498
|
|
|
26380
26499
|
|
|
26381
|
-
|
|
26382
26500
|
class DbHeaderChain {
|
|
26383
26501
|
blocks;
|
|
26384
26502
|
constructor(blocks) {
|
|
@@ -26449,7 +26567,7 @@ class chain_stf_OnChain {
|
|
|
26449
26567
|
// chapter 13: https://graypaper.fluffylabs.dev/#/68eaa1f/18b60118b601?v=0.6.4
|
|
26450
26568
|
statistics;
|
|
26451
26569
|
isReadyForNextEpoch = Promise.resolve(false);
|
|
26452
|
-
constructor(chainSpec, state, blocks, hasher, pvm
|
|
26570
|
+
constructor(chainSpec, state, blocks, hasher, pvm) {
|
|
26453
26571
|
this.chainSpec = chainSpec;
|
|
26454
26572
|
this.state = state;
|
|
26455
26573
|
this.hasher = hasher;
|
|
@@ -26743,7 +26861,6 @@ function state_loader_loadState(spec, blake2b, keyvals) {
|
|
|
26743
26861
|
|
|
26744
26862
|
|
|
26745
26863
|
|
|
26746
|
-
|
|
26747
26864
|
class StateTransitionGenesis {
|
|
26748
26865
|
static fromJson = {
|
|
26749
26866
|
header: headerFromJson,
|
|
@@ -26773,7 +26890,7 @@ class StateTransition {
|
|
|
26773
26890
|
}
|
|
26774
26891
|
const keccakHasher = keccak_KeccakHasher.create();
|
|
26775
26892
|
const cachedBlocks = new Map();
|
|
26776
|
-
function loadBlocks(testPath) {
|
|
26893
|
+
function loadBlocks(testPath, spec) {
|
|
26777
26894
|
const dir = path.dirname(testPath);
|
|
26778
26895
|
const fromCache = cachedBlocks.get(dir);
|
|
26779
26896
|
if (fromCache !== undefined) {
|
|
@@ -26781,20 +26898,19 @@ function loadBlocks(testPath) {
|
|
|
26781
26898
|
}
|
|
26782
26899
|
const blocks = [];
|
|
26783
26900
|
for (const file of fs.readdirSync(dir)) {
|
|
26784
|
-
if (!file.endsWith(".
|
|
26901
|
+
if (!file.endsWith(".bin")) {
|
|
26785
26902
|
continue;
|
|
26786
26903
|
}
|
|
26787
|
-
const data = fs.readFileSync(path.join(dir, file)
|
|
26788
|
-
const parsed = JSON.parse(data);
|
|
26904
|
+
const data = fs.readFileSync(path.join(dir, file));
|
|
26789
26905
|
try {
|
|
26790
|
-
if (file.endsWith("genesis.
|
|
26791
|
-
const
|
|
26792
|
-
const genesisBlock = Block.create({ header:
|
|
26906
|
+
if (file.endsWith("genesis.bin")) {
|
|
26907
|
+
const genesis = Decoder.decodeObject(StateTransitionGenesis.Codec, data, spec);
|
|
26908
|
+
const genesisBlock = Block.create({ header: genesis.header, extrinsic: emptyBlock().extrinsic });
|
|
26793
26909
|
blocks.push(genesisBlock);
|
|
26794
26910
|
}
|
|
26795
26911
|
else {
|
|
26796
|
-
const
|
|
26797
|
-
blocks.push(
|
|
26912
|
+
const test = Decoder.decodeObject(StateTransition.Codec, data, spec);
|
|
26913
|
+
blocks.push(test.block);
|
|
26798
26914
|
}
|
|
26799
26915
|
}
|
|
26800
26916
|
catch {
|
|
@@ -26816,20 +26932,20 @@ const jamConformance070V0Spec = new ChainSpec({
|
|
|
26816
26932
|
...chain_spec_tinyChainSpec,
|
|
26817
26933
|
maxLookupAnchorAge: numbers_tryAsU32(14_400),
|
|
26818
26934
|
});
|
|
26819
|
-
async function runStateTransition(testContent, testPath, t) {
|
|
26935
|
+
async function runStateTransition(testContent, testPath, t, chainSpec) {
|
|
26820
26936
|
const blake2b = await Blake2b.createHasher();
|
|
26821
26937
|
// a bit of a hack, but the new value for `maxLookupAnchorAge` was proposed with V1
|
|
26822
26938
|
// version of the fuzzer, yet these tests were still depending on the older value.
|
|
26823
26939
|
// To simplify the chain spec, we just special case this one vector here.
|
|
26824
26940
|
const spec = testPath.includes("fuzz-reports/0.7.0/traces/1756548916/00000082.json")
|
|
26825
26941
|
? jamConformance070V0Spec
|
|
26826
|
-
:
|
|
26942
|
+
: chainSpec;
|
|
26827
26943
|
const preState = loadState(spec, blake2b, testContent.pre_state.keyvals);
|
|
26828
26944
|
const postState = loadState(spec, blake2b, testContent.post_state.keyvals);
|
|
26829
26945
|
const preStateRoot = preState.backend.getRootHash(blake2b);
|
|
26830
26946
|
const postStateRoot = postState.backend.getRootHash(blake2b);
|
|
26831
26947
|
const blockView = blockAsView(spec, testContent.block);
|
|
26832
|
-
const allBlocks = loadBlocks(testPath);
|
|
26948
|
+
const allBlocks = loadBlocks(testPath, spec);
|
|
26833
26949
|
const myBlockIndex = allBlocks.findIndex(({ header }) => header.timeSlotIndex === testContent.block.header.timeSlotIndex);
|
|
26834
26950
|
const previousBlocks = allBlocks.slice(0, myBlockIndex);
|
|
26835
26951
|
const hasher = new TransitionHasher(spec, await keccakHasher, blake2b);
|
|
@@ -26838,7 +26954,7 @@ async function runStateTransition(testContent, testPath, t) {
|
|
|
26838
26954
|
const headerHash = hasher.header(blockView.header.view());
|
|
26839
26955
|
return new WithHash(headerHash.hash, blockView);
|
|
26840
26956
|
}));
|
|
26841
|
-
const stf = new OnChain(spec, preState, blocksDb, hasher);
|
|
26957
|
+
const stf = new OnChain(spec, preState, blocksDb, hasher, PvmBackend.BuiltIn);
|
|
26842
26958
|
// verify that we compute the state root exactly the same.
|
|
26843
26959
|
assert.deepStrictEqual(testContent.pre_state.state_root.toString(), preStateRoot.toString());
|
|
26844
26960
|
assert.deepStrictEqual(testContent.post_state.state_root.toString(), postStateRoot.toString());
|