@typeberry/convert 0.1.2-726ffce6 → 0.1.2-7ebe1f6

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