@typeberry/convert 0.1.2-ced735c9 → 0.1.2-ef67dce

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.
Files changed (3) hide show
  1. package/index.js +166 -37
  2. package/index.js.map +1 -1
  3. package/package.json +1 -1
package/index.js CHANGED
@@ -4695,8 +4695,8 @@ function print(level, levelAndName, strings, data) {
4695
4695
  return;
4696
4696
  }
4697
4697
  const lvlText = Level[level].padEnd(5);
4698
- const val = strings.map((v, idx) => `${v}${data[idx]}`);
4699
- const msg = `${lvlText} [${levelAndName[1]}] ${val}`;
4698
+ const val = strings.map((v, idx) => `${v}${idx < data.length ? data[idx] : ""}`);
4699
+ const msg = `${lvlText} [${levelAndName[1]}] ${val.join("")}`;
4700
4700
  if (level === Level.WARN) {
4701
4701
  console.warn(msg);
4702
4702
  }
@@ -17473,6 +17473,17 @@ class page_range_PageRange {
17473
17473
  }
17474
17474
  return new page_range_PageRange(start, length);
17475
17475
  }
17476
+ /** Returns true if the page range is wrapped (`start` >= `end`) and is not empty */
17477
+ isWrapped() {
17478
+ return this.start >= this.end && !this.isEmpty();
17479
+ }
17480
+ /** Checks if given page number is within the range */
17481
+ isInRange(page) {
17482
+ if (this.isWrapped()) {
17483
+ return page >= this.start || page < this.end;
17484
+ }
17485
+ return page >= this.start && page < this.end;
17486
+ }
17476
17487
  /** Checks if a range is empty (`length === 0`) */
17477
17488
  isEmpty() {
17478
17489
  return this.length === 0;
@@ -17852,10 +17863,11 @@ class memory_builder_MemoryBuilder {
17852
17863
  startHeapIndex (${startHeapIndex}) has to be less than or equal to endHeapIndex (${endHeapIndex})
17853
17864
  `;
17854
17865
  this.ensureNotFinalized();
17855
- const range = MemoryRange.fromStartAndLength(startHeapIndex, endHeapIndex - startHeapIndex);
17856
- const pages = PageRange.fromMemoryRange(range);
17857
- for (const pageNumber of pages) {
17858
- if (this.initialMemory.has(pageNumber)) {
17866
+ const heapRange = MemoryRange.fromStartAndLength(startHeapIndex, endHeapIndex - startHeapIndex);
17867
+ const heapPagesRange = PageRange.fromMemoryRange(heapRange);
17868
+ const initializedPageNumbers = Array.from(this.initialMemory.keys());
17869
+ for (const pageNumber of initializedPageNumbers) {
17870
+ if (heapPagesRange.isInRange(pageNumber)) {
17859
17871
  throw new IncorrectSbrkIndex();
17860
17872
  }
17861
17873
  }
@@ -26809,6 +26821,12 @@ async function runPvmTest(testContent) {
26809
26821
 
26810
26822
 
26811
26823
 
26824
+ function looseType(output) {
26825
+ return {
26826
+ value: output.value,
26827
+ encode: output.encode,
26828
+ };
26829
+ }
26812
26830
  const SUPPORTED_TYPES = [
26813
26831
  {
26814
26832
  name: "block",
@@ -26826,8 +26844,12 @@ const SUPPORTED_TYPES = [
26826
26844
  run(spec, data, option) {
26827
26845
  const header = data;
26828
26846
  if (option === "as-hash") {
26829
- return hashBytes(encoder_Encoder.encodeObject(header_Header.Codec, header, spec));
26847
+ return looseType({
26848
+ value: hashBytes(encoder_Encoder.encodeObject(header_Header.Codec, header, spec)),
26849
+ encode: descriptors_codec.bytes(hash_HASH_SIZE),
26850
+ });
26830
26851
  }
26852
+ throw new Error(`Invalid processing option: ${option}`);
26831
26853
  },
26832
26854
  },
26833
26855
  },
@@ -26871,11 +26893,17 @@ const SUPPORTED_TYPES = [
26871
26893
  run(spec, data, option) {
26872
26894
  const state = data;
26873
26895
  if (option === "as-entries") {
26874
- return Object.fromEntries(state_entries_StateEntries.serializeInMemory(spec, state));
26896
+ return looseType({
26897
+ value: Object.fromEntries(state_entries_StateEntries.serializeInMemory(spec, state)),
26898
+ });
26875
26899
  }
26876
26900
  if (option === "as-root-hash") {
26877
- return state_entries_StateEntries.serializeInMemory(spec, state).getRootHash();
26901
+ return looseType({
26902
+ value: state_entries_StateEntries.serializeInMemory(spec, state).getRootHash(),
26903
+ encode: descriptors_codec.bytes(hash_HASH_SIZE),
26904
+ });
26878
26905
  }
26906
+ throw new Error(`Invalid processing option: ${option}`);
26879
26907
  },
26880
26908
  },
26881
26909
  },
@@ -26885,19 +26913,39 @@ const SUPPORTED_TYPES = [
26885
26913
  decode: StateTransitionGenesis.Codec,
26886
26914
  json: () => StateTransitionGenesis.fromJson,
26887
26915
  process: {
26888
- options: ["as-state", "as-jip4"],
26916
+ options: ["as-state", "as-jip4", "as-fuzz-message"],
26889
26917
  run(spec, data, option) {
26890
26918
  const test = data;
26891
26919
  if (option === "as-state") {
26892
- return stateFromKeyvals(spec, test.state);
26920
+ return looseType({
26921
+ value: stateFromKeyvals(spec, test.state),
26922
+ });
26893
26923
  }
26894
26924
  if (option === "as-jip4") {
26895
26925
  const genesisState = new Map(test.state.keyvals.map((x) => [x.key, x.value]));
26896
- return JipChainSpec.create({
26897
- genesisHeader: encoder_Encoder.encodeObject(header_Header.Codec, test.header, spec),
26898
- genesisState,
26926
+ return looseType({
26927
+ value: JipChainSpec.create({
26928
+ genesisHeader: encoder_Encoder.encodeObject(header_Header.Codec, test.header, spec),
26929
+ genesisState,
26930
+ }),
26931
+ });
26932
+ }
26933
+ if (option === "as-fuzz-message") {
26934
+ const init = Initialize.create({
26935
+ header: test.header,
26936
+ keyvals: test.state.keyvals,
26937
+ ancestry: [],
26938
+ });
26939
+ const msg = {
26940
+ type: types_MessageType.Initialize,
26941
+ value: init,
26942
+ };
26943
+ return looseType({
26944
+ value: msg,
26945
+ encode: types_messageCodec,
26899
26946
  });
26900
26947
  }
26948
+ throw new Error(`Invalid processing option: ${option}`);
26901
26949
  },
26902
26950
  },
26903
26951
  },
@@ -26907,15 +26955,32 @@ const SUPPORTED_TYPES = [
26907
26955
  decode: StateTransition.Codec,
26908
26956
  json: () => StateTransition.fromJson,
26909
26957
  process: {
26910
- options: ["as-pre-state", "as-post-state"],
26958
+ options: ["as-pre-state", "as-post-state", "as-fuzz-message"],
26911
26959
  run(spec, data, option) {
26912
26960
  const test = data;
26913
26961
  if (option === "as-pre-state") {
26914
- return stateFromKeyvals(spec, test.pre_state);
26962
+ return looseType({
26963
+ value: stateFromKeyvals(spec, test.pre_state),
26964
+ });
26915
26965
  }
26916
26966
  if (option === "as-post-state") {
26917
- return stateFromKeyvals(spec, test.post_state);
26967
+ return looseType({
26968
+ value: stateFromKeyvals(spec, test.post_state),
26969
+ });
26970
+ }
26971
+ if (option === "as-fuzz-message") {
26972
+ const encoded = encoder_Encoder.encodeObject(block_Block.Codec, test.block, spec);
26973
+ const blockView = decoder_Decoder.decodeObject(block_Block.Codec.View, encoded, spec);
26974
+ const msg = {
26975
+ type: types_MessageType.ImportBlock,
26976
+ value: blockView,
26977
+ };
26978
+ return looseType({
26979
+ value: msg,
26980
+ encode: types_messageCodec,
26981
+ });
26918
26982
  }
26983
+ throw new Error(`Invalid processing option: ${option}`);
26919
26984
  },
26920
26985
  },
26921
26986
  },
@@ -26938,7 +27003,7 @@ const HELP = `
26938
27003
  @typeberry/convert ${package_namespaceObject.rE} by Fluffy Labs.
26939
27004
 
26940
27005
  Usage:
26941
- @typeberry/convert [options] <bin-hex-or-json-input-file> <type> [process] [output-format]
27006
+ @typeberry/convert [options] <bin-hex-or-json-input-file> <type> [process] [output-format] [output-file]
26942
27007
 
26943
27008
  Attempts to read provided input file as 'type' and output in requested 'output-format'.
26944
27009
  For some 'type's it's additionally possible to process the data before outputting it.
@@ -26947,6 +27012,7 @@ The input type is detected from file extension ('.bin', '.hex' or '.json').
26947
27012
  Example usage:
26948
27013
  @typeberry/convert ./genesis-header.json header to-hex
26949
27014
  @typeberry/convert ./state-snapshot.json state-dump as-entries to-json
27015
+ @typeberry/convert ./state-snapshot.json stf-vector as-fuzz-message to-bin msg0.bin
26950
27016
 
26951
27017
  Options:
26952
27018
  --flavor - chain spec flavor, either 'full' or 'tiny'.
@@ -26956,6 +27022,7 @@ Output formats:
26956
27022
  to-print - Print the object to the console
26957
27023
  to-json - JSON format (when supported)
26958
27024
  to-hex - JAM-codec hex-encoded string (when supported)
27025
+ to-bin - JAM-codec binary data (when supported)
26959
27026
  to-repl - Start a JavaScript REPL with the data loaded into a variable
26960
27027
 
26961
27028
  Input types:
@@ -26978,6 +27045,7 @@ var OutputFormat;
26978
27045
  OutputFormat["Print"] = "to-print";
26979
27046
  OutputFormat["Json"] = "to-json";
26980
27047
  OutputFormat["Hex"] = "to-hex";
27048
+ OutputFormat["Bin"] = "to-bin";
26981
27049
  OutputFormat["Repl"] = "to-repl";
26982
27050
  })(OutputFormat || (OutputFormat = {}));
26983
27051
  function parseArgs(cliInput, withRelPath) {
@@ -26999,14 +27067,16 @@ function parseArgs(cliInput, withRelPath) {
26999
27067
  const type = parseType(args._.shift());
27000
27068
  const maybeProcess = args._.shift();
27001
27069
  const maybeOutputFormat = args._.shift();
27070
+ const maybeDestination = args._.shift();
27002
27071
  assertNoMoreArgs(args);
27003
- const { process, format } = getProcessAndOutput(type, maybeProcess, maybeOutputFormat);
27072
+ const { process, format, destination } = getProcessFormatAndDestination(type, maybeProcess, maybeOutputFormat, maybeDestination);
27004
27073
  return {
27005
27074
  flavor: chainSpec.flavor,
27006
27075
  type,
27007
27076
  process,
27008
27077
  inputPath: withRelPath(input),
27009
27078
  outputFormat: format,
27079
+ destination,
27010
27080
  };
27011
27081
  }
27012
27082
  function parseType(type) {
@@ -27032,10 +27102,21 @@ function parseOutputFormat(output) {
27032
27102
  return OutputFormat.Json;
27033
27103
  case OutputFormat.Repl:
27034
27104
  return OutputFormat.Repl;
27105
+ case OutputFormat.Bin:
27106
+ return OutputFormat.Bin;
27035
27107
  default:
27036
27108
  throw new Error(`Invalid output format: '${output}'.`);
27037
27109
  }
27038
27110
  }
27111
+ function parseProcess(processOptions, maybeProcess) {
27112
+ if (maybeProcess === undefined) {
27113
+ return null;
27114
+ }
27115
+ if (!processOptions.includes(maybeProcess)) {
27116
+ throw new Error(`Incorrect processing option: ${maybeProcess}. Expected one of: ${processOptions}.`);
27117
+ }
27118
+ return maybeProcess;
27119
+ }
27039
27120
  // TODO [ToDr] Consider sharing that?
27040
27121
  function parseOption(args, option, parser, defaultValue) {
27041
27122
  if (args[option] === undefined) {
@@ -27071,33 +27152,64 @@ function assertNoMoreArgs(args) {
27071
27152
  throw new Error(`Unrecognized options: '${keysLeft}'`);
27072
27153
  }
27073
27154
  }
27074
- function getProcessAndOutput(type, maybeProcess, maybeOutputFormat) {
27155
+ function getProcessFormatAndDestination(type, maybeProcess, maybeOutputFormat, maybeDestination) {
27156
+ const defaultProcess = "";
27075
27157
  const defaultFormat = parseOutputFormat(undefined);
27076
- const options = type.process?.options ?? [];
27077
- // we have both options, so we expect them in the right order.
27078
- if (maybeProcess !== undefined && maybeOutputFormat !== undefined) {
27158
+ const processOptions = type.process?.options ?? [];
27159
+ // we have all three so it must be in order
27160
+ if (maybeProcess !== undefined && maybeOutputFormat !== undefined && maybeDestination !== undefined) {
27079
27161
  const format = parseOutputFormat(maybeOutputFormat);
27080
- if (!options.includes(maybeProcess)) {
27081
- throw new Error(`Incorrect processing option: ${maybeProcess}. Expected one of: ${options}.`);
27082
- }
27083
- return { process: maybeProcess, format };
27162
+ const process = parseProcess(processOptions, maybeProcess) ?? defaultProcess;
27163
+ const destination = maybeDestination;
27164
+ throwIfDumpNotSupported(format, destination);
27165
+ return { process, format, destination };
27166
+ }
27167
+ // we have either:
27168
+ // 1. process + format
27169
+ // 2. format + destination
27170
+ if (maybeProcess !== undefined && maybeOutputFormat !== undefined) {
27171
+ // we've got processing first, so easy-peasy
27172
+ if (processOptions.includes(maybeProcess)) {
27173
+ const format = parseOutputFormat(maybeOutputFormat);
27174
+ throwIfDumpNotSupported(format, null);
27175
+ return { process: maybeProcess, format, destination: null };
27176
+ }
27177
+ // first one has to be format then.
27178
+ const format = parseOutputFormat(maybeProcess);
27179
+ const destination = maybeOutputFormat;
27180
+ throwIfDumpNotSupported(format, destination);
27181
+ return { process: defaultProcess, format, destination };
27084
27182
  }
27085
27183
  // only one parameter, but it can be either output or processing.
27184
+ const destination = null;
27086
27185
  if (maybeProcess !== undefined) {
27087
- if (options.includes(maybeProcess)) {
27088
- return { process: maybeProcess, format: defaultFormat };
27186
+ if (processOptions.includes(maybeProcess)) {
27187
+ return { process: maybeProcess, format: defaultFormat, destination };
27089
27188
  }
27090
27189
  // now it should be output format, but we want to give a better error message,
27091
27190
  // if user mispelled processing.
27092
27191
  try {
27093
27192
  const format = parseOutputFormat(maybeProcess);
27094
- return { process: "", format };
27193
+ throwIfDumpNotSupported(format, destination);
27194
+ return { process: defaultProcess, format, destination };
27095
27195
  }
27096
27196
  catch {
27097
27197
  throw new Error(`'${maybeProcess}' is neither output format nor processing parameter.`);
27098
27198
  }
27099
27199
  }
27100
- return { process: "", format: defaultFormat };
27200
+ return { process: defaultProcess, format: defaultFormat, destination };
27201
+ }
27202
+ function throwIfDumpNotSupported(format, destination) {
27203
+ if (destination !== null) {
27204
+ if (format === OutputFormat.Print || format === OutputFormat.Repl) {
27205
+ throw new Error(`Dumping to file is not supported for ${format}`);
27206
+ }
27207
+ }
27208
+ else {
27209
+ if (format === OutputFormat.Bin) {
27210
+ throw new Error(`${format} requires destination file`);
27211
+ }
27212
+ }
27101
27213
  }
27102
27214
 
27103
27215
  // EXTERNAL MODULE: ./node_modules/json-bigint-patch/dist/index.js
@@ -27157,9 +27269,13 @@ function loadInputFile(file, withRelPath) {
27157
27269
  throw new Error("Input file format unsupported.");
27158
27270
  }
27159
27271
  function dumpOutput(spec, data, type, outputFormat, args, withRelPath) {
27272
+ const { destination } = args;
27273
+ const dump = destination !== null
27274
+ ? (v) => external_node_fs_default().writeFileSync(withRelPath(destination), v)
27275
+ : (v) => console.info(v);
27160
27276
  switch (outputFormat) {
27161
27277
  case OutputFormat.Print: {
27162
- console.info(`${debug_inspect(data)}`);
27278
+ dump(`${debug_inspect(data)}`);
27163
27279
  return;
27164
27280
  }
27165
27281
  case OutputFormat.Hex: {
@@ -27167,13 +27283,24 @@ function dumpOutput(spec, data, type, outputFormat, args, withRelPath) {
27167
27283
  throw new Error(`${type.name} does not support encoding to JAM codec.`);
27168
27284
  }
27169
27285
  const encoded = encoder_Encoder.encodeObject(type.encode, data, spec);
27170
- console.info(`${encoded}`);
27286
+ dump(`${encoded}`);
27287
+ return;
27288
+ }
27289
+ case OutputFormat.Bin: {
27290
+ if (type.encode === undefined) {
27291
+ throw new Error(`${type.name} does not support encoding to JAM codec.`);
27292
+ }
27293
+ if (destination === null) {
27294
+ throw new Error(`${OutputFormat.Bin} requires destination file.`);
27295
+ }
27296
+ const encoded = encoder_Encoder.encodeObject(type.encode, data, spec);
27297
+ dump(encoded.raw);
27171
27298
  return;
27172
27299
  }
27173
27300
  case OutputFormat.Json: {
27174
27301
  // TODO [ToDr] this will probably not work for all cases,
27175
27302
  // but for now may be good enough.
27176
- console.info(toJson(data));
27303
+ dump(toJson(data));
27177
27304
  return;
27178
27305
  }
27179
27306
  case OutputFormat.Repl: {
@@ -27250,12 +27377,14 @@ function processOutput(spec, data, type, process) {
27250
27377
  if (type.process === undefined || !type.process.options.includes(process)) {
27251
27378
  throw new Error(`Unsupported processing: '${process}' for '${type.name}'`);
27252
27379
  }
27380
+ const processed = type.process.run(spec, data, process);
27253
27381
  return {
27254
- processed: type.process.run(spec, data, process),
27382
+ processed: processed.value,
27255
27383
  type: {
27256
27384
  ...type,
27257
- // disable encoding, since it won't match
27258
- encode: undefined,
27385
+ name: `${type.name}(${process})`,
27386
+ // use encoding from processed type
27387
+ encode: processed.encode,
27259
27388
  },
27260
27389
  };
27261
27390
  }