@typeberry/lib 0.5.3-fb6e98a → 0.5.4-472e282

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 (162) hide show
  1. package/package.json +1 -1
  2. package/packages/core/networking/certificate.d.ts.map +1 -1
  3. package/packages/core/networking/certificate.js +1 -0
  4. package/packages/core/networking/package.json +1 -1
  5. package/packages/core/networking/setup.d.ts.map +1 -1
  6. package/packages/core/networking/setup.js +16 -12
  7. package/packages/core/telemetry/package.json +1 -1
  8. package/packages/core/utils/compatibility.d.ts +0 -1
  9. package/packages/core/utils/compatibility.d.ts.map +1 -1
  10. package/packages/core/utils/compatibility.js +1 -2
  11. package/packages/core/utils/compatibility.test.js +6 -10
  12. package/packages/extensions/ipc/jamnp/handler.d.ts +5 -4
  13. package/packages/extensions/ipc/jamnp/handler.d.ts.map +1 -1
  14. package/packages/extensions/ipc/jamnp/handler.js +59 -34
  15. package/packages/extensions/ipc/jamnp/stream.d.ts +6 -4
  16. package/packages/extensions/ipc/jamnp/stream.d.ts.map +1 -1
  17. package/packages/jam/block/index.d.ts +11 -11
  18. package/packages/jam/block/index.d.ts.map +1 -1
  19. package/packages/jam/block/index.js +11 -11
  20. package/packages/jam/block/work-package.d.ts +3 -1
  21. package/packages/jam/block/work-package.d.ts.map +1 -1
  22. package/packages/jam/block/work-package.js +6 -2
  23. package/packages/jam/block-json/block.d.ts +125 -0
  24. package/packages/jam/block-json/block.d.ts.map +1 -1
  25. package/packages/jam/block-json/block.js +9 -2
  26. package/packages/jam/database-lmdb/states.test.js +3 -5
  27. package/packages/jam/fuzz-proto/v1/handler.d.ts +1 -1
  28. package/packages/jam/fuzz-proto/v1/handler.d.ts.map +1 -1
  29. package/packages/jam/fuzz-proto/v1/handler.js +43 -19
  30. package/packages/jam/fuzz-proto/v1/types.d.ts +1 -1
  31. package/packages/jam/jam-host-calls/accumulate/bless.d.ts.map +1 -1
  32. package/packages/jam/jam-host-calls/accumulate/bless.js +6 -10
  33. package/packages/jam/jam-host-calls/accumulate/bless.test.js +32 -72
  34. package/packages/jam/jam-host-calls/accumulate/new.d.ts.map +1 -1
  35. package/packages/jam/jam-host-calls/accumulate/new.js +2 -4
  36. package/packages/jam/jam-host-calls/accumulate/new.test.js +4 -5
  37. package/packages/jam/jam-host-calls/general/fetch.d.ts +1 -57
  38. package/packages/jam/jam-host-calls/general/fetch.d.ts.map +1 -1
  39. package/packages/jam/jam-host-calls/general/fetch.js +6 -29
  40. package/packages/jam/jam-host-calls/general/fetch.test.js +2 -58
  41. package/packages/jam/jamnp-s/peers.d.ts.map +1 -1
  42. package/packages/jam/jamnp-s/peers.js +10 -0
  43. package/packages/jam/jamnp-s/protocol/ce-128-block-request.d.ts +1 -1
  44. package/packages/jam/jamnp-s/protocol/ce-128-block-request.d.ts.map +1 -1
  45. package/packages/jam/jamnp-s/protocol/ce-128-block-request.js +10 -8
  46. package/packages/jam/jamnp-s/protocol/ce-129-state-request.d.ts.map +1 -1
  47. package/packages/jam/jamnp-s/protocol/ce-129-state-request.js +11 -9
  48. package/packages/jam/jamnp-s/protocol/ce-131-ce-132-safrole-ticket-distribution.d.ts +3 -3
  49. package/packages/jam/jamnp-s/protocol/ce-131-ce-132-safrole-ticket-distribution.d.ts.map +1 -1
  50. package/packages/jam/jamnp-s/protocol/ce-131-ce-132-safrole-ticket-distribution.js +2 -2
  51. package/packages/jam/jamnp-s/protocol/ce-133-work-package-submission.d.ts +6 -6
  52. package/packages/jam/jamnp-s/protocol/ce-133-work-package-submission.d.ts.map +1 -1
  53. package/packages/jam/jamnp-s/protocol/ce-133-work-package-submission.js +2 -2
  54. package/packages/jam/jamnp-s/protocol/ce-134-work-package-sharing.d.ts.map +1 -1
  55. package/packages/jam/jamnp-s/protocol/ce-134-work-package-sharing.js +8 -6
  56. package/packages/jam/jamnp-s/protocol/ce-135-work-report-distribution.d.ts +16 -16
  57. package/packages/jam/jamnp-s/protocol/ce-135-work-report-distribution.d.ts.map +1 -1
  58. package/packages/jam/jamnp-s/protocol/ce-135-work-report-distribution.js +2 -2
  59. package/packages/jam/jamnp-s/protocol/stream.d.ts +13 -7
  60. package/packages/jam/jamnp-s/protocol/stream.d.ts.map +1 -1
  61. package/packages/jam/jamnp-s/protocol/stream.js +5 -4
  62. package/packages/jam/jamnp-s/protocol/test-utils.d.ts +1 -1
  63. package/packages/jam/jamnp-s/protocol/test-utils.d.ts.map +1 -1
  64. package/packages/jam/jamnp-s/protocol/test-utils.js +9 -12
  65. package/packages/jam/jamnp-s/protocol/up-0-block-announcement.d.ts +2 -2
  66. package/packages/jam/jamnp-s/protocol/up-0-block-announcement.d.ts.map +1 -1
  67. package/packages/jam/jamnp-s/protocol/up-0-block-announcement.js +1 -1
  68. package/packages/jam/jamnp-s/stream-manager.d.ts.map +1 -1
  69. package/packages/jam/jamnp-s/stream-manager.js +7 -5
  70. package/packages/jam/jamnp-s/stream-manager.test.js +8 -5
  71. package/packages/jam/jamnp-s/tasks/sync.js +1 -1
  72. package/packages/jam/node/jam-config.d.ts +4 -1
  73. package/packages/jam/node/jam-config.d.ts.map +1 -1
  74. package/packages/jam/node/jam-config.js +6 -2
  75. package/packages/jam/node/main.d.ts.map +1 -1
  76. package/packages/jam/node/main.js +5 -4
  77. package/packages/jam/node/package.json +1 -1
  78. package/packages/jam/node/reader.d.ts +25 -25
  79. package/packages/jam/node/workers.d.ts +183 -183
  80. package/packages/jam/state/accumulation-queue.d.ts +26 -26
  81. package/packages/jam/state/assurances.d.ts +26 -26
  82. package/packages/jam/state/privileged-services.d.ts +1 -1
  83. package/packages/jam/state/privileged-services.d.ts.map +1 -1
  84. package/packages/jam/state/privileged-services.js +1 -6
  85. package/packages/jam/state/service.d.ts +1 -1
  86. package/packages/jam/state/service.d.ts.map +1 -1
  87. package/packages/jam/state/statistics.d.ts +0 -8
  88. package/packages/jam/state/statistics.d.ts.map +1 -1
  89. package/packages/jam/state/statistics.js +14 -44
  90. package/packages/jam/state/statistics.test.js +1 -8
  91. package/packages/jam/state/test.utils.d.ts +1 -1
  92. package/packages/jam/state/test.utils.d.ts.map +1 -1
  93. package/packages/jam/state/test.utils.js +4 -22
  94. package/packages/jam/state-json/accounts.d.ts +10 -0
  95. package/packages/jam/state-json/accounts.d.ts.map +1 -1
  96. package/packages/jam/state-json/accounts.js +47 -19
  97. package/packages/jam/state-json/dump.d.ts.map +1 -1
  98. package/packages/jam/state-json/dump.js +5 -9
  99. package/packages/jam/state-json/dump.test.js +2 -10
  100. package/packages/jam/state-json/statistics.d.ts +1 -1
  101. package/packages/jam/state-json/statistics.d.ts.map +1 -1
  102. package/packages/jam/state-json/statistics.js +1 -13
  103. package/packages/jam/state-merkleization/in-memory-state-codec.d.ts +29 -31
  104. package/packages/jam/state-merkleization/in-memory-state-codec.d.ts.map +1 -1
  105. package/packages/jam/state-merkleization/serialize.d.ts +4 -4
  106. package/packages/jam/state-merkleization/serialize.d.ts.map +1 -1
  107. package/packages/jam/state-merkleization/serialize.js +5 -8
  108. package/packages/jam/state-merkleization/serialized-state-view.d.ts.map +1 -1
  109. package/packages/jam/state-merkleization/state-entries.test.js +1 -7
  110. package/packages/jam/state-vectors/index.d.ts +377 -5
  111. package/packages/jam/state-vectors/index.d.ts.map +1 -1
  112. package/packages/jam/state-vectors/index.js +3 -3
  113. package/packages/jam/transition/accumulate/accumulate-state.d.ts +1 -2
  114. package/packages/jam/transition/accumulate/accumulate-state.d.ts.map +1 -1
  115. package/packages/jam/transition/accumulate/accumulate-utils.d.ts.map +1 -1
  116. package/packages/jam/transition/accumulate/accumulate-utils.js +2 -6
  117. package/packages/jam/transition/accumulate/accumulate-utils.test.js +2 -4
  118. package/packages/jam/transition/accumulate/accumulate.d.ts.map +1 -1
  119. package/packages/jam/transition/accumulate/accumulate.js +11 -20
  120. package/packages/jam/transition/accumulate/index.d.ts +0 -1
  121. package/packages/jam/transition/accumulate/index.d.ts.map +1 -1
  122. package/packages/jam/transition/accumulate/index.js +0 -1
  123. package/packages/jam/transition/accumulate/operand.d.ts +7 -7
  124. package/packages/jam/transition/chain-stf.d.ts +3 -5
  125. package/packages/jam/transition/chain-stf.d.ts.map +1 -1
  126. package/packages/jam/transition/chain-stf.js +5 -29
  127. package/packages/jam/transition/disputes/disputes.test.data2.d.ts +3 -3
  128. package/packages/jam/transition/disputes/disputes.test.data2.d.ts.map +1 -1
  129. package/packages/jam/transition/externalities/accumulate-externalities.d.ts.map +1 -1
  130. package/packages/jam/transition/externalities/accumulate-externalities.js +22 -49
  131. package/packages/jam/transition/externalities/accumulate-externalities.test.js +8 -72
  132. package/packages/jam/transition/externalities/fetch-externalities.d.ts +3 -22
  133. package/packages/jam/transition/externalities/fetch-externalities.d.ts.map +1 -1
  134. package/packages/jam/transition/externalities/fetch-externalities.js +3 -55
  135. package/packages/jam/transition/externalities/fetch-externalities.test.js +199 -112
  136. package/packages/jam/transition/reports/error.d.ts +3 -1
  137. package/packages/jam/transition/reports/error.d.ts.map +1 -1
  138. package/packages/jam/transition/reports/error.js +2 -0
  139. package/packages/jam/transition/reports/verify-basic.d.ts.map +1 -1
  140. package/packages/jam/transition/reports/verify-basic.js +10 -0
  141. package/packages/jam/transition/reports/verify-basic.test.js +29 -0
  142. package/packages/jam/transition/statistics.d.ts +0 -7
  143. package/packages/jam/transition/statistics.d.ts.map +1 -1
  144. package/packages/jam/transition/statistics.js +2 -11
  145. package/packages/jam/transition/statistics.test.js +0 -40
  146. package/packages/workers/block-authorship/generator.test.d.ts +2 -0
  147. package/packages/workers/block-authorship/generator.test.d.ts.map +1 -0
  148. package/packages/workers/block-authorship/generator.test.js +200 -0
  149. package/packages/workers/block-authorship/main.d.ts.map +1 -1
  150. package/packages/workers/block-authorship/main.js +23 -4
  151. package/packages/workers/block-authorship/package.json +1 -1
  152. package/packages/workers/block-authorship/protocol.d.ts +53 -51
  153. package/packages/workers/block-authorship/protocol.d.ts.map +1 -1
  154. package/packages/workers/block-authorship/protocol.js +6 -3
  155. package/packages/workers/importer/importer.d.ts.map +1 -1
  156. package/packages/workers/importer/importer.js +0 -1
  157. package/packages/workers/importer/package.json +1 -1
  158. package/packages/workers/importer/protocol.d.ts +54 -54
  159. package/packages/workers/jam-network/protocol.d.ts +79 -79
  160. package/packages/jam/transition/accumulate/deferred-transfers.d.ts +0 -36
  161. package/packages/jam/transition/accumulate/deferred-transfers.d.ts.map +0 -1
  162. package/packages/jam/transition/accumulate/deferred-transfers.js +0 -94
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typeberry/lib",
3
- "version": "0.5.3-fb6e98a",
3
+ "version": "0.5.4-472e282",
4
4
  "description": "Typeberry Library",
5
5
  "main": "./bin/lib/index.js",
6
6
  "types": "./bin/lib/index.d.ts",
@@ -1 +1 @@
1
- {"version":3,"file":"certificate.d.ts","sourceRoot":"","sources":["../../../../../packages/core/networking/certificate.ts"],"names":[],"mappings":"AAAA,OAAe,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAGtD,OAAO,KAAK,IAAI,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAS,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAqB,KAAK,UAAU,EAAE,KAAK,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAErF,OAAO,EAAgB,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAezC,oBAAY,eAAe;IACzB,aAAa,IAAI;IACjB,UAAU,IAAI;IACd,qBAAqB,IAAI;IACzB,eAAe,IAAI;IACnB,kBAAkB,IAAI;CACvB;AAED,MAAM,MAAM,QAAQ,GAAG;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,UAAU,CAAC;CACjB,CAAC;AAEF,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAwDvG;AAED,wBAAsB,sBAAsB,IAAI,OAAO,CAAC;IACtD,SAAS,EAAE,UAAU,CAAC;IACtB,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC,CAcD;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,cAAc,mBAQ5D;AAED,wFAAwF;AACxF,wBAAsB,mBAAmB,CAAC,EACxC,MAAM,EACN,cAAc,EACd,aAAa,EACb,iBAAsB,EACtB,gBAAqB,EACrB,GAAgB,GACjB,EAAE;IACD,MAAM,EAAE,SAAS,CAAC;IAClB,cAAc,EAAE,cAAc,CAAC;IAC/B,aAAa,EAAE,cAAc,CAAC;IAC9B,iBAAiB,CAAC,EAAE,KAAK,CAAC;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACvD,gBAAgB,CAAC,EAAE,KAAK,CAAC;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACtD,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ,GAAG,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CA6EhC;AAED,wBAAgB,UAAU,CAAC,aAAa,EAAE,SAAS,UAElD;AACD,wBAAgB,UAAU,CAAC,aAAa,EAAE,UAAU,UAGnD;AA4BD,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,UAEnD;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,UAAU,CAAC;IACtB,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC;AAEF,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,CAAC,WAAW,GAAG,cAAc,CAkBpF"}
1
+ {"version":3,"file":"certificate.d.ts","sourceRoot":"","sources":["../../../../../packages/core/networking/certificate.ts"],"names":[],"mappings":"AAAA,OAAe,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAGtD,OAAO,KAAK,IAAI,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAS,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAqB,KAAK,UAAU,EAAE,KAAK,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAErF,OAAO,EAAgB,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAezC,oBAAY,eAAe;IACzB,aAAa,IAAI;IACjB,UAAU,IAAI;IACd,qBAAqB,IAAI;IACzB,eAAe,IAAI;IACnB,kBAAkB,IAAI;CACvB;AAED,MAAM,MAAM,QAAQ,GAAG;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,UAAU,CAAC;CACjB,CAAC;AAEF,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAyDvG;AAED,wBAAsB,sBAAsB,IAAI,OAAO,CAAC;IACtD,SAAS,EAAE,UAAU,CAAC;IACtB,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC,CAcD;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,cAAc,mBAQ5D;AAED,wFAAwF;AACxF,wBAAsB,mBAAmB,CAAC,EACxC,MAAM,EACN,cAAc,EACd,aAAa,EACb,iBAAsB,EACtB,gBAAqB,EACrB,GAAgB,GACjB,EAAE;IACD,MAAM,EAAE,SAAS,CAAC;IAClB,cAAc,EAAE,cAAc,CAAC;IAC/B,aAAa,EAAE,cAAc,CAAC;IAC9B,iBAAiB,CAAC,EAAE,KAAK,CAAC;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACvD,gBAAgB,CAAC,EAAE,KAAK,CAAC;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACtD,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ,GAAG,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CA6EhC;AAED,wBAAgB,UAAU,CAAC,aAAa,EAAE,SAAS,UAElD;AACD,wBAAgB,UAAU,CAAC,aAAa,EAAE,UAAU,UAGnD;AA4BD,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,UAEnD;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,UAAU,CAAC;IACtB,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC;AAEF,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,CAAC,WAAW,GAAG,cAAc,CAkBpF"}
@@ -54,6 +54,7 @@ export async function verifyCertificate(certs) {
54
54
  }
55
55
  const key = Buffer.from(jwk.x ?? "", "base64url");
56
56
  if (!xc.verify(xc.publicKey)) {
57
+ logger.log `Certificate validation failed: incorrect signature`;
57
58
  return Result.error(VerifyCertError.IncorrectSignature, () => "Certificate validation failed: incorrect signature");
58
59
  }
59
60
  const publicKey = Bytes.fromBlob(new Uint8Array(key), ED25519_KEY_BYTES);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typeberry/networking",
3
- "version": "0.5.3",
3
+ "version": "0.5.4",
4
4
  "description": "QUIC-based p2p networking.",
5
5
  "license": "MPL-2.0",
6
6
  "author": "Fluffy Labs",
@@ -1 +1 @@
1
- {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../../../packages/core/networking/setup.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAgBhE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAMhD,sCAAsC;AACtC,MAAM,MAAM,OAAO,GAAG;IACpB,yBAAyB;IACzB,GAAG,EAAE,WAAW,CAAC;IACjB,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB,CAAC;AAQF,qBAAa,IAAI;IACf,6DAA6D;WAChD,KAAK,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC;CAkKlF"}
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../../../packages/core/networking/setup.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAiBhE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAMhD,sCAAsC;AACtC,MAAM,MAAM,OAAO,GAAG;IACpB,yBAAyB;IACzB,GAAG,EAAE,WAAW,CAAC;IACjB,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB,CAAC;AAQF,qBAAa,IAAI;IACf,6DAA6D;WAChD,KAAK,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC;CAsKlF"}
@@ -3,7 +3,7 @@ import { events, QUICClient, QUICServer, QUICSocket } from "@matrixai/quic";
3
3
  import { BytesBlob } from "#@typeberry/bytes";
4
4
  import { Level, Logger } from "#@typeberry/logger";
5
5
  import { now } from "#@typeberry/utils";
6
- import { altNameRaw, certToPEM, ed25519AsJsonWebKeyPair, generateCertificate, privateKeyToPEM, } from "./certificate.js";
6
+ import { altNameRaw, certToPEM, ed25519AsJsonWebKeyPair, generateCertificate, privateKeyToPEM, verifyCertificate, } from "./certificate.js";
7
7
  import { getQuicClientCrypto, getQuicServerCrypto } from "./crypto.js";
8
8
  import * as metrics from "./metrics.js";
9
9
  import { peerVerification } from "./peer-verification.js";
@@ -34,7 +34,6 @@ export class Quic {
34
34
  subjectKeyPair: keyPair,
35
35
  issuerKeyPair: keyPair,
36
36
  });
37
- const lastConnectedPeer = peerVerification();
38
37
  // QUICConfig
39
38
  const config = {
40
39
  keepAliveIntervalTime: 3000,
@@ -43,7 +42,9 @@ export class Quic {
43
42
  cert: certToPEM(cert),
44
43
  key: privKeyPEM,
45
44
  verifyPeer: true,
46
- verifyCallback: lastConnectedPeer.verifyCallback,
45
+ // Server accepts TLS and verifies the certificate in the connection handler
46
+ // (EventQUICServerConnection). Client overrides this with peerVerification() per dial.
47
+ verifyCallback: async () => undefined,
47
48
  };
48
49
  logger.info `🆔 Peer id: ** ${altNameRaw(key.pubKey)}@${host}:${port} ** (pubkey: ${key.pubKey})`;
49
50
  // Shared injected UDP socket
@@ -67,27 +68,30 @@ export class Quic {
67
68
  const conn = ev.detail;
68
69
  const peerAddress = `${conn.remoteHost}:${conn.remotePort}`;
69
70
  networkMetrics.recordConnectingIn(peerAddress);
70
- if (lastConnectedPeer.info === null) {
71
- networkMetrics.recordConnectInFailed("no_peer_info");
71
+ // Verify the peer's certificate and extract peer info.
72
+ const remoteCerts = conn.getRemoteCertsChain();
73
+ const verification = await verifyCertificate(remoteCerts);
74
+ if (verification.isError) {
75
+ networkMetrics.recordConnectInFailed("cert_verification_failed");
72
76
  await conn.stop();
73
77
  return;
74
78
  }
75
- if (lastConnectedPeer.info.key.isEqualTo(key.pubKey)) {
79
+ const peerInfo = verification.ok;
80
+ if (peerInfo.key.isEqualTo(key.pubKey)) {
76
81
  logger.log `🛜 Rejecting connection from ourself from ${conn.remoteHost}:${conn.remotePort}`;
77
82
  networkMetrics.recordConnectionRefused(peerAddress);
78
83
  await conn.stop({ isApp: true, errorCode: CloseReason.ConnectionFromOurself });
79
84
  return;
80
85
  }
81
- if (peers.isConnected(lastConnectedPeer.info.id)) {
82
- logger.log `🛜 Rejecting duplicate connection with peer ${lastConnectedPeer.info.id} from ${conn.remoteHost}:${conn.remotePort}`;
86
+ if (peers.isConnected(peerInfo.id)) {
87
+ logger.log `🛜 Rejecting duplicate connection with peer ${peerInfo.id} from ${conn.remoteHost}:${conn.remotePort}`;
83
88
  networkMetrics.recordConnectionRefused(peerAddress);
84
- await conn.stop({ isApp: true, errorCode: CloseReason.DuplicateConnection });
89
+ await conn.stop({ isApp: true, errorCode: CloseReason.DuplicateConnection, force: false });
85
90
  return;
86
91
  }
87
92
  logger.log `🛜 Server handshake with ${conn.remoteHost}:${conn.remotePort}`;
88
- newPeer(conn, lastConnectedPeer.info, "in");
89
- networkMetrics.recordConnectedIn(lastConnectedPeer.info.id);
90
- lastConnectedPeer.info = null;
93
+ newPeer(conn, peerInfo, "in");
94
+ networkMetrics.recordConnectedIn(peerInfo.id);
91
95
  await conn.start();
92
96
  });
93
97
  // connecting to a peer
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typeberry/telemetry",
3
- "version": "0.5.3",
3
+ "version": "0.5.4",
4
4
  "description": "OpenTelemetry initialization utilities for Typeberry",
5
5
  "license": "MPL-2.0",
6
6
  "author": "Fluffy Labs",
@@ -1,5 +1,4 @@
1
1
  export declare enum GpVersion {
2
- V0_7_0 = "0.7.0",
3
2
  V0_7_1 = "0.7.1",
4
3
  V0_7_2 = "0.7.2"
5
4
  }
@@ -1 +1 @@
1
- {"version":3,"file":"compatibility.d.ts","sourceRoot":"","sources":["../../../../../packages/core/utils/compatibility.ts"],"names":[],"mappings":"AAEA,oBAAY,SAAS;IACnB,MAAM,UAAU;IAChB,MAAM,UAAU;IAChB,MAAM,UAAU;CACjB;AAED,oBAAY,SAAS;IACnB,SAAS,cAAc;CACxB;AAKD,eAAO,MAAM,aAAa,sBAAsB,CAAC;AACjD,eAAO,MAAM,eAAe,mBAAmB,CAAC;AAEhD,eAAO,IAAI,eAAe,WAAyD,CAAC;AACpF,eAAO,IAAI,aAAa,WAAqD,CAAC;AA8B9E,qBAAa,aAAa;IACxB,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS;IAInC,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,SAAS;IAIrC,MAAM,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,SAAS,EAAE;IAOjC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,SAAS;IASpD,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,SAAS;IAQ1C;;;;;;OAMG;IACH,MAAM,CAAC,sBAAsB,CAAC,CAAC,EAAE,EAC/B,QAAQ,EACR,QAAQ,GACT,EAAE;QACD,QAAQ,EAAE,CAAC,CAAC;QACZ,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;KACzC,GAAG,CAAC;CASN"}
1
+ {"version":3,"file":"compatibility.d.ts","sourceRoot":"","sources":["../../../../../packages/core/utils/compatibility.ts"],"names":[],"mappings":"AAEA,oBAAY,SAAS;IACnB,MAAM,UAAU;IAChB,MAAM,UAAU;CACjB;AAED,oBAAY,SAAS;IACnB,SAAS,cAAc;CACxB;AAKD,eAAO,MAAM,aAAa,sBAAsB,CAAC;AACjD,eAAO,MAAM,eAAe,mBAAmB,CAAC;AAEhD,eAAO,IAAI,eAAe,WAAyD,CAAC;AACpF,eAAO,IAAI,aAAa,WAAqD,CAAC;AA8B9E,qBAAa,aAAa;IACxB,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS;IAInC,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,SAAS;IAIrC,MAAM,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,SAAS,EAAE;IAOjC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,SAAS;IASpD,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,SAAS;IAQ1C;;;;;;OAMG;IACH,MAAM,CAAC,sBAAsB,CAAC,CAAC,EAAE,EAC/B,QAAQ,EACR,QAAQ,GACT,EAAE;QACD,QAAQ,EAAE,CAAC,CAAC;QACZ,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;KACzC,GAAG,CAAC;CASN"}
@@ -1,7 +1,6 @@
1
1
  import { env } from "./env.js";
2
2
  export var GpVersion;
3
3
  (function (GpVersion) {
4
- GpVersion["V0_7_0"] = "0.7.0";
5
4
  GpVersion["V0_7_1"] = "0.7.1";
6
5
  GpVersion["V0_7_2"] = "0.7.2";
7
6
  })(GpVersion || (GpVersion = {}));
@@ -10,7 +9,7 @@ export var TestSuite;
10
9
  TestSuite["W3F_DAVXY"] = "w3f-davxy";
11
10
  })(TestSuite || (TestSuite = {}));
12
11
  // NOTE: Also acts as a supported versions
13
- const ALL_VERSIONS_IN_ORDER = [GpVersion.V0_7_0, GpVersion.V0_7_1, GpVersion.V0_7_2];
12
+ const ALL_VERSIONS_IN_ORDER = [GpVersion.V0_7_1, GpVersion.V0_7_2];
14
13
  export const DEFAULT_SUITE = TestSuite.W3F_DAVXY;
15
14
  export const DEFAULT_VERSION = GpVersion.V0_7_2;
16
15
  export let CURRENT_VERSION = parseCurrentVersion(env.GP_VERSION) ?? DEFAULT_VERSION;
@@ -15,22 +15,21 @@ describe("GrayPaper compatibility", { concurrency: false }, () => {
15
15
  assert.equal(Compatibility.is(defaultVersion), true);
16
16
  });
17
17
  it("Should check with env variable if env variable was set", () => {
18
- const gpVersion = GpVersion.V0_7_0;
18
+ const gpVersion = GpVersion.V0_7_2;
19
19
  Compatibility.override(gpVersion);
20
20
  assert.equal(Compatibility.is(gpVersion), true);
21
21
  });
22
22
  it("Should check an order of versions (isGreaterOrEqual)", () => {
23
- const gpVersion = GpVersion.V0_7_0;
23
+ const gpVersion = GpVersion.V0_7_1;
24
24
  Compatibility.override(gpVersion);
25
- assert.equal(Compatibility.isGreaterOrEqual(GpVersion.V0_7_0), true);
26
- assert.equal(Compatibility.isGreaterOrEqual(GpVersion.V0_7_1), false);
25
+ assert.equal(Compatibility.isGreaterOrEqual(GpVersion.V0_7_1), true);
27
26
  assert.equal(Compatibility.isGreaterOrEqual(GpVersion.V0_7_2), false);
28
27
  });
29
28
  it("Should order values by versions and get the one for highest version matching", () => {
30
29
  const gpVersion = GpVersion.V0_7_1;
31
30
  Compatibility.override(gpVersion);
32
31
  const record = {
33
- [GpVersion.V0_7_0]: "low",
32
+ [GpVersion.V0_7_1]: "low",
34
33
  [GpVersion.V0_7_2]: "high",
35
34
  };
36
35
  const result = Compatibility.selectIfGreaterOrEqual({ fallback: "default", versions: record });
@@ -40,7 +39,6 @@ describe("GrayPaper compatibility", { concurrency: false }, () => {
40
39
  const gpVersion = GpVersion.V0_7_1;
41
40
  Compatibility.override(gpVersion);
42
41
  const record = {
43
- [GpVersion.V0_7_0]: "low",
44
42
  [GpVersion.V0_7_1]: "mid",
45
43
  [GpVersion.V0_7_2]: "high",
46
44
  };
@@ -51,7 +49,6 @@ describe("GrayPaper compatibility", { concurrency: false }, () => {
51
49
  const gpVersion = GpVersion.V0_7_2;
52
50
  Compatibility.override(gpVersion);
53
51
  const record = {
54
- [GpVersion.V0_7_0]: "low",
55
52
  [GpVersion.V0_7_1]: "mid",
56
53
  [GpVersion.V0_7_2]: "high",
57
54
  };
@@ -59,17 +56,16 @@ describe("GrayPaper compatibility", { concurrency: false }, () => {
59
56
  assert.equal(result, "high");
60
57
  });
61
58
  it("Should return default if no version is greater or equal", () => {
62
- const gpVersion = GpVersion.V0_7_0;
59
+ const gpVersion = GpVersion.V0_7_1;
63
60
  Compatibility.override(gpVersion);
64
61
  const record = {
65
- [GpVersion.V0_7_1]: "mid",
66
62
  [GpVersion.V0_7_2]: "high",
67
63
  };
68
64
  const result = Compatibility.selectIfGreaterOrEqual({ fallback: "default", versions: record });
69
65
  assert.equal(result, "default");
70
66
  });
71
67
  it("Should return default if record is empty", () => {
72
- const gpVersion = GpVersion.V0_7_0;
68
+ const gpVersion = GpVersion.V0_7_1;
73
69
  Compatibility.override(gpVersion);
74
70
  const result = Compatibility.selectIfGreaterOrEqual({ fallback: "default", versions: {} });
75
71
  assert.equal(result, "default");
@@ -1,8 +1,8 @@
1
1
  import { BytesBlob } from "#@typeberry/bytes";
2
2
  import type { IpcHandler } from "#@typeberry/fuzz-proto";
3
- import type { StreamHandler, StreamId, StreamKindOf, StreamMessageSender } from "#@typeberry/jamnp-s";
3
+ import { type StreamHandler, type StreamId, type StreamKindOf, type StreamMessageSender } from "#@typeberry/jamnp-s";
4
4
  import type { IpcSender } from "../server.js";
5
- import { NewStream } from "./stream.js";
5
+ import { type IpcStreamId, NewStream } from "./stream.js";
6
6
  export type ResponseHandler = (err: Error | null, response?: BytesBlob) => void;
7
7
  export declare class JamnpIpcHandler implements IpcHandler {
8
8
  private readonly sender;
@@ -31,9 +31,10 @@ export declare class JamnpIpcHandler implements IpcHandler {
31
31
  waitForEnd(): Promise<void>;
32
32
  }
33
33
  declare class EnvelopeSender implements StreamMessageSender {
34
- readonly streamId: StreamId;
34
+ private readonly ipcStreamId;
35
35
  private readonly sender;
36
- constructor(streamId: StreamId, sender: IpcSender);
36
+ readonly streamId: StreamId;
37
+ constructor(ipcStreamId: IpcStreamId, sender: IpcSender);
37
38
  open(newStream: NewStream): void;
38
39
  bufferAndSend(msg: BytesBlob): boolean;
39
40
  close(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../../../packages/extensions/ipc/jamnp/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAc,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEjH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAsC,MAAM,aAAa,CAAC;AAE5E,MAAM,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI,EAAE,QAAQ,CAAC,EAAE,SAAS,KAAK,IAAI,CAAC;AAWhF,qBAAa,eAAgB,YAAW,UAAU;IAUpC,OAAO,CAAC,QAAQ,CAAC,MAAM;IATnC,gCAAgC;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2C;IACnE,yDAAyD;IACzD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqC;IACpE,0DAA0D;IAC1D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA6C;IAC5E,sCAAsC;IACtC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;gBAED,MAAM,EAAE,SAAS;IAe9C,gCAAgC;IAChC,sBAAsB,CAAC,GAAG,QAAQ,EAAE,aAAa,EAAE;IAMnD,0DAA0D;IAC1D,gBAAgB,CAAC,QAAQ,SAAS,aAAa,EAC7C,UAAU,EAAE,YAAY,CAAC,QAAQ,CAAC,EAClC,IAAI,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,KAAK,IAAI,GACxD,IAAI;IAWP,uCAAuC;IACvC,aAAa,CAAC,QAAQ,SAAS,aAAa,EAC1C,IAAI,EAAE,YAAY,CAAC,QAAQ,CAAC,EAC5B,IAAI,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,KAAK,IAAI,GACxD,IAAI;IA2BP,8CAA8C;IACxC,eAAe,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAkDrD,yDAAyD;IACzD,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE;IAiBpC,qEAAqE;IACrE,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAI5B;AAED,cAAM,cAAe,YAAW,mBAAmB;aAE/B,QAAQ,EAAE,QAAQ;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADP,QAAQ,EAAE,QAAQ,EACjB,MAAM,EAAE,SAAS;IAGpC,IAAI,CAAC,SAAS,EAAE,SAAS;IAUzB,aAAa,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO;IAWtC,KAAK,IAAI,IAAI;CAYd"}
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../../../packages/extensions/ipc/jamnp/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,QAAQ,EAEb,KAAK,YAAY,EACjB,KAAK,mBAAmB,EAEzB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,KAAK,WAAW,EAAE,SAAS,EAAsC,MAAM,aAAa,CAAC;AAS9F,MAAM,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI,EAAE,QAAQ,CAAC,EAAE,SAAS,KAAK,IAAI,CAAC;AAWhF,qBAAa,eAAgB,YAAW,UAAU;IAUpC,OAAO,CAAC,QAAQ,CAAC,MAAM;IATnC,gCAAgC;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8C;IACtE,yDAAyD;IACzD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwC;IACvE,0DAA0D;IAC1D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA6C;IAC5E,sCAAsC;IACtC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;gBAED,MAAM,EAAE,SAAS;IAe9C,gCAAgC;IAChC,sBAAsB,CAAC,GAAG,QAAQ,EAAE,aAAa,EAAE;IAMnD,0DAA0D;IAC1D,gBAAgB,CAAC,QAAQ,SAAS,aAAa,EAC7C,UAAU,EAAE,YAAY,CAAC,QAAQ,CAAC,EAClC,IAAI,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,KAAK,IAAI,GACxD,IAAI;IAWP,uCAAuC;IACvC,aAAa,CAAC,QAAQ,SAAS,aAAa,EAC1C,IAAI,EAAE,YAAY,CAAC,QAAQ,CAAC,EAC5B,IAAI,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,KAAK,IAAI,GACxD,IAAI;IA2BP,8CAA8C;IACxC,eAAe,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAmErD,yDAAyD;IACzD,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE;IAkBpC,qEAAqE;IACrE,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAI5B;AAED,cAAM,cAAe,YAAW,mBAAmB;IAI/C,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJzB,SAAgB,QAAQ,EAAE,QAAQ,CAAC;gBAGhB,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,SAAS;IAKpC,IAAI,CAAC,SAAS,EAAE,SAAS;IAUzB,aAAa,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO;IAWtC,KAAK,IAAI,IAAI;CAYd"}
@@ -1,7 +1,14 @@
1
1
  import { BytesBlob } from "#@typeberry/bytes";
2
2
  import { Decoder, Encoder } from "#@typeberry/codec";
3
+ import { tryAsStreamId, } from "#@typeberry/jamnp-s";
3
4
  import { Logger } from "#@typeberry/logger";
5
+ import { assertNever } from "#@typeberry/utils";
4
6
  import { NewStream, StreamEnvelope, StreamEnvelopeType } from "./stream.js";
7
+ const IPC_PEER_ID = "ipc-peer";
8
+ /** Construct a protocol-level StreamId from an IPC-level numeric stream ID. */
9
+ function toStreamId(ipcStreamId) {
10
+ return tryAsStreamId(`${IPC_PEER_ID}:${ipcStreamId}`);
11
+ }
5
12
  const logger = Logger.new(import.meta.filename, "ext-ipc-jamnp");
6
13
  export class JamnpIpcHandler {
7
14
  sender;
@@ -37,9 +44,9 @@ export class JamnpIpcHandler {
37
44
  /** Re-use an existing stream of given kind if present. */
38
45
  withStreamOfKind(streamKind, work) {
39
46
  // find first stream id with given kind
40
- for (const [streamId, handler] of this.streams.entries()) {
47
+ for (const [ipcStreamId, handler] of this.streams.entries()) {
41
48
  if (handler.kind === streamKind) {
42
- work(handler, new EnvelopeSender(streamId, this.sender));
49
+ work(handler, new EnvelopeSender(ipcStreamId, this.sender));
43
50
  return;
44
51
  }
45
52
  }
@@ -52,19 +59,19 @@ export class JamnpIpcHandler {
52
59
  throw new Error(`Stream with unregistered handler of kind: ${kind} was requested to be opened.`);
53
60
  }
54
61
  // pick a stream id
55
- const getRandomStreamId = () => Math.floor(Math.random() * 2 ** 16);
62
+ const getRandomIpcStreamId = () => Math.floor(Math.random() * 2 ** 32);
56
63
  const streams = this.streams;
57
- const streamId = (function findStreamId() {
58
- const s = getRandomStreamId();
64
+ const ipcStreamId = (function findStreamId() {
65
+ const s = getRandomIpcStreamId();
59
66
  if (!streams.has(s)) {
60
67
  return s;
61
68
  }
62
69
  return findStreamId();
63
70
  })();
64
71
  // register the stream
65
- this.streams.set(streamId, handler);
66
- this.pendingStreams.set(streamId, true);
67
- const sender = new EnvelopeSender(streamId, this.sender);
72
+ this.streams.set(ipcStreamId, handler);
73
+ this.pendingStreams.set(ipcStreamId, true);
74
+ const sender = new EnvelopeSender(ipcStreamId, this.sender);
68
75
  sender.open(NewStream.create({ streamByte: kind }));
69
76
  work(handler, sender);
70
77
  }
@@ -72,24 +79,24 @@ export class JamnpIpcHandler {
72
79
  async onSocketMessage(msg) {
73
80
  // decode the message as `StreamEnvelope`
74
81
  const envelope = Decoder.decodeObject(StreamEnvelope.Codec, msg);
75
- const streamId = envelope.streamId;
76
- logger.log `[${streamId}] incoming message: ${envelope.type} ${envelope.data}`;
82
+ const ipcStreamId = envelope.streamId;
83
+ logger.log `[${ipcStreamId}] incoming message: ${envelope.type} ${envelope.data}`;
77
84
  // check if this is a already known stream id
78
- const streamHandler = this.streams.get(streamId);
79
- const streamSender = new EnvelopeSender(streamId, this.sender);
85
+ const streamHandler = this.streams.get(ipcStreamId);
86
+ const streamSender = new EnvelopeSender(ipcStreamId, this.sender);
80
87
  // we don't know that stream yet, so it has to be a new one
81
88
  if (streamHandler === undefined) {
82
89
  // closing or message of unknown stream - ignore.
83
90
  if (envelope.type !== StreamEnvelopeType.Open) {
84
- logger.warn `[${streamId}] (unknown) got invalid type ${envelope.type}.`;
91
+ logger.warn `[${ipcStreamId}] (unknown) got invalid type ${envelope.type}.`;
85
92
  return;
86
93
  }
87
94
  const newStream = Decoder.decodeObject(NewStream.Codec, envelope.data);
88
95
  const handler = this.streamHandlers.get(newStream.streamByte);
89
96
  if (handler !== undefined) {
90
- logger.log `[${streamId}] new stream for ${handler.kind}`;
97
+ logger.log `[${ipcStreamId}] new stream for ${handler.kind}`;
91
98
  // insert the stream
92
- this.streams.set(streamId, handler);
99
+ this.streams.set(ipcStreamId, handler);
93
100
  // Just send back the same stream byte.
94
101
  streamSender.open(newStream);
95
102
  return;
@@ -98,31 +105,47 @@ export class JamnpIpcHandler {
98
105
  streamSender.close();
99
106
  return;
100
107
  }
101
- // close the stream
102
- if (envelope.type === StreamEnvelopeType.Close) {
103
- const handler = this.streams.get(streamId);
104
- handler?.onClose(streamId, false);
105
- this.streams.delete(streamId);
106
- return;
107
- }
108
- if (envelope.type !== StreamEnvelopeType.Msg) {
108
+ if (envelope.type === StreamEnvelopeType.Open) {
109
109
  // display a warning but only if the stream was not pending for confirmation.
110
- if (!this.pendingStreams.delete(streamId)) {
111
- logger.warn `[${streamId}] got invalid type ${envelope.type}.`;
110
+ if (!this.pendingStreams.delete(ipcStreamId)) {
111
+ logger.warn `[${ipcStreamId}] got invalid type ${envelope.type}.`;
112
112
  }
113
113
  return;
114
114
  }
115
+ // reject stream messages without open ack first.
116
+ if (this.pendingStreams.has(ipcStreamId)) {
117
+ logger.warn `[${ipcStreamId}] got invalid type ${envelope.type}. Expected Open.`;
118
+ // closing the connection and removing the stream from pending.
119
+ this.pendingStreams.delete(ipcStreamId);
120
+ // the stream should not be in the collection yet, but we remove it just for safety.
121
+ this.streams.delete(ipcStreamId);
122
+ streamSender.close();
123
+ return;
124
+ }
115
125
  // this is a known stream, so just dispatch the message.
116
- streamHandler.onStreamMessage(streamSender, envelope.data);
126
+ if (envelope.type === StreamEnvelopeType.Msg) {
127
+ streamHandler.onStreamMessage(streamSender, envelope.data);
128
+ return;
129
+ }
130
+ // close the stream
131
+ if (envelope.type === StreamEnvelopeType.Close) {
132
+ streamHandler.onClose(toStreamId(ipcStreamId), false);
133
+ this.streams.delete(ipcStreamId);
134
+ // not really needed, but just for sure.
135
+ this.pendingStreams.delete(ipcStreamId);
136
+ return;
137
+ }
138
+ assertNever(envelope.type);
117
139
  }
118
140
  /** Notify about termination of the underlying socket. */
119
141
  onClose({ error }) {
120
142
  logger.log `Closing the handler. Reason: ${error !== undefined ? error.message : "close"}.`;
121
143
  // Socket closed - we should probably clear everything.
122
- for (const [streamId, handler] of this.streams.entries()) {
123
- handler.onClose(streamId, error === undefined);
144
+ for (const [ipcStreamId, handler] of this.streams.entries()) {
145
+ handler.onClose(toStreamId(ipcStreamId), error !== undefined);
124
146
  }
125
147
  this.streams.clear();
148
+ this.pendingStreams.clear();
126
149
  // finish the handler.
127
150
  this.onEnd.finished = true;
128
151
  if (error !== undefined) {
@@ -139,24 +162,26 @@ export class JamnpIpcHandler {
139
162
  }
140
163
  }
141
164
  class EnvelopeSender {
142
- streamId;
165
+ ipcStreamId;
143
166
  sender;
144
- constructor(streamId, sender) {
145
- this.streamId = streamId;
167
+ streamId;
168
+ constructor(ipcStreamId, sender) {
169
+ this.ipcStreamId = ipcStreamId;
146
170
  this.sender = sender;
171
+ this.streamId = toStreamId(ipcStreamId);
147
172
  }
148
173
  open(newStream) {
149
174
  const msg = Encoder.encodeObject(NewStream.Codec, newStream);
150
- this.sender.send(Encoder.encodeObject(StreamEnvelope.Codec, StreamEnvelope.create({ streamId: this.streamId, type: StreamEnvelopeType.Open, data: msg })));
175
+ this.sender.send(Encoder.encodeObject(StreamEnvelope.Codec, StreamEnvelope.create({ streamId: this.ipcStreamId, type: StreamEnvelopeType.Open, data: msg })));
151
176
  }
152
177
  bufferAndSend(msg) {
153
- this.sender.send(Encoder.encodeObject(StreamEnvelope.Codec, StreamEnvelope.create({ streamId: this.streamId, type: StreamEnvelopeType.Msg, data: msg })));
178
+ this.sender.send(Encoder.encodeObject(StreamEnvelope.Codec, StreamEnvelope.create({ streamId: this.ipcStreamId, type: StreamEnvelopeType.Msg, data: msg })));
154
179
  // we are buffering until we run OOM
155
180
  return true;
156
181
  }
157
182
  close() {
158
183
  this.sender.send(Encoder.encodeObject(StreamEnvelope.Codec, StreamEnvelope.create({
159
- streamId: this.streamId,
184
+ streamId: this.ipcStreamId,
160
185
  type: StreamEnvelopeType.Close,
161
186
  data: BytesBlob.blobFromNumbers([]),
162
187
  })));
@@ -1,18 +1,20 @@
1
1
  import type { BytesBlob } from "#@typeberry/bytes";
2
2
  import { type CodecRecord } from "#@typeberry/codec";
3
- import type { StreamId, StreamKind } from "#@typeberry/jamnp-s";
4
- import { type U8 } from "#@typeberry/numbers";
3
+ import type { StreamKind } from "#@typeberry/jamnp-s";
4
+ import { type U8, type U32 } from "#@typeberry/numbers";
5
+ /** IPC-level stream identifier (u32), used for multiplexing streams over a single socket. */
6
+ export type IpcStreamId = U32;
5
7
  export declare enum StreamEnvelopeType {
6
8
  Msg = 0,
7
9
  Open = 1,
8
10
  Close = 2
9
11
  }
10
12
  export declare class StreamEnvelope {
11
- readonly streamId: StreamId;
13
+ readonly streamId: IpcStreamId;
12
14
  readonly type: StreamEnvelopeType;
13
15
  readonly data: BytesBlob;
14
16
  static Codec: import("@typeberry/codec").Descriptor<StreamEnvelope, import("@typeberry/codec").ViewOf<StreamEnvelope, {
15
- streamId: import("@typeberry/codec").Descriptor<import("@typeberry/numbers").U32, import("@typeberry/bytes").Bytes<4>>;
17
+ streamId: import("@typeberry/codec").Descriptor<U32, import("@typeberry/bytes").Bytes<4>>;
16
18
  type: import("@typeberry/codec").Descriptor<StreamEnvelopeType, U8>;
17
19
  data: import("@typeberry/codec").Descriptor<BytesBlob, BytesBlob>;
18
20
  }>>;
@@ -1 +1 @@
1
- {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../../../../../packages/extensions/ipc/jamnp/stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,KAAK,WAAW,EAAS,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAW,KAAK,EAAE,EAAE,MAAM,oBAAoB,CAAC;AAEtD,oBAAY,kBAAkB;IAC5B,GAAG,IAAI;IACP,IAAI,IAAI;IACR,KAAK,IAAI;CACV;AAED,qBAAa,cAAc;aA0BP,QAAQ,EAAE,QAAQ;aAClB,IAAI,EAAE,kBAAkB;aACxB,IAAI,EAAE,SAAS;IA3BjC,MAAM,CAAC,KAAK;;;;QAkBT;IAEH,MAAM,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,WAAW,CAAC,cAAc,CAAC;IAInE,OAAO;CAKR;AAED,qBAAa,SAAS;aASgB,UAAU,EAAE,UAAU;IAR1D,MAAM,CAAC,KAAK;;QAET;IAEH,MAAM,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,EAAE,WAAW,CAAC,SAAS,CAAC;IAIpD,OAAO;CACR"}
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../../../../../packages/extensions/ipc/jamnp/stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,KAAK,WAAW,EAAS,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAW,KAAK,EAAE,EAAE,KAAK,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAEhE,6FAA6F;AAC7F,MAAM,MAAM,WAAW,GAAG,GAAG,CAAC;AAE9B,oBAAY,kBAAkB;IAC5B,GAAG,IAAI;IACP,IAAI,IAAI;IACR,KAAK,IAAI;CACV;AAED,qBAAa,cAAc;aA0BP,QAAQ,EAAE,WAAW;aACrB,IAAI,EAAE,kBAAkB;aACxB,IAAI,EAAE,SAAS;IA3BjC,MAAM,CAAC,KAAK;;;;QAkBT;IAEH,MAAM,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,WAAW,CAAC,cAAc,CAAC;IAInE,OAAO;CAKR;AAED,qBAAa,SAAS;aASgB,UAAU,EAAE,UAAU;IAR1D,MAAM,CAAC,KAAK;;QAET;IAEH,MAAM,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,EAAE,WAAW,CAAC,SAAS,CAAC;IAIpD,OAAO;CACR"}
@@ -1,18 +1,18 @@
1
- export * as assurances from "./assurances.js";
1
+ export * from "./assurances.js";
2
2
  export * from "./block.js";
3
- export * as codecUtils from "./codec-utils.js";
3
+ export * from "./codec-utils.js";
4
4
  export * from "./common.js";
5
- export * as disputes from "./disputes.js";
6
- export * as guarantees from "./guarantees.js";
5
+ export * from "./disputes.js";
6
+ export * from "./guarantees.js";
7
7
  export * from "./hash.js";
8
8
  export * from "./header.js";
9
- export * as preimage from "./preimage.js";
10
- export * as refineContext from "./refine-context.js";
11
- export * as tickets from "./tickets.js";
9
+ export * from "./preimage.js";
10
+ export * from "./refine-context.js";
11
+ export * from "./tickets.js";
12
12
  export * from "./utils.js";
13
- export * as workItem from "./work-item.js";
13
+ export * from "./work-item.js";
14
14
  export * from "./work-item-segment.js";
15
- export * as workPackage from "./work-package.js";
16
- export * as workReport from "./work-report.js";
17
- export * as workResult from "./work-result.js";
15
+ export * from "./work-package.js";
16
+ export * from "./work-report.js";
17
+ export * from "./work-result.js";
18
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/block/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAC;AAC9C,cAAc,YAAY,CAAC;AAC3B,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAC/C,cAAc,aAAa,CAAC;AAC5B,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAC;AAC9C,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,aAAa,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,cAAc,YAAY,CAAC;AAC3B,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/block/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC"}
@@ -1,17 +1,17 @@
1
- export * as assurances from "./assurances.js";
1
+ export * from "./assurances.js";
2
2
  export * from "./block.js";
3
- export * as codecUtils from "./codec-utils.js";
3
+ export * from "./codec-utils.js";
4
4
  export * from "./common.js";
5
- export * as disputes from "./disputes.js";
6
- export * as guarantees from "./guarantees.js";
5
+ export * from "./disputes.js";
6
+ export * from "./guarantees.js";
7
7
  export * from "./hash.js";
8
8
  export * from "./header.js";
9
- export * as preimage from "./preimage.js";
10
- export * as refineContext from "./refine-context.js";
11
- export * as tickets from "./tickets.js";
9
+ export * from "./preimage.js";
10
+ export * from "./refine-context.js";
11
+ export * from "./tickets.js";
12
12
  export * from "./utils.js";
13
- export * as workItem from "./work-item.js";
13
+ export * from "./work-item.js";
14
14
  export * from "./work-item-segment.js";
15
- export * as workPackage from "./work-package.js";
16
- export * as workReport from "./work-report.js";
17
- export * as workResult from "./work-result.js";
15
+ export * from "./work-package.js";
16
+ export * from "./work-report.js";
17
+ export * from "./work-result.js";
@@ -10,8 +10,10 @@ import { WorkItem } from "./work-item.js";
10
10
  /** Possible number of work items in the package or results in the report. */
11
11
  /** Constrained by I=16 https://graypaper.fluffylabs.dev/#/68eaa1f/417a00417a00?v=0.6.4 */
12
12
  export type WorkItemsCount = U8;
13
- /** Verify the value is within the `WorkItemsCount` bounds. */
13
+ /** Convert the value to `WorkItemsCount` bounds. */
14
14
  export declare function tryAsWorkItemsCount(len: number): WorkItemsCount;
15
+ /** Verify the value is within the `WorkItemsCount` bounds. */
16
+ export declare function isWorkItemsCount(len: number): len is WorkItemsCount;
15
17
  /** Minimal number of work items in the work package or results in work report. */
16
18
  export declare const MIN_NUMBER_OF_WORK_ITEMS = 1;
17
19
  /** `I`: Maximal number of work items in the work package or results in work report. */
@@ -1 +1 @@
1
- {"version":3,"file":"work-package.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/block/work-package.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,KAAK,WAAW,EAAS,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,EAAW,KAAK,EAAE,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAS,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,6EAA6E;AAC7E,0FAA0F;AAC1F,MAAM,MAAM,cAAc,GAAG,EAAE,CAAC;AAEhC,8DAA8D;AAC9D,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAM/D;AAED,kFAAkF;AAClF,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAC1C,uFAAuF;AACvF,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C;;;;;;GAMG;AACH,qBAAa,WAAY,SAAQ,SAAS;IAyBtC,wDAAwD;aACxC,aAAa,EAAE,SAAS;IACxC,kEAAkE;aAClD,YAAY,EAAE,SAAS;IACvC,mCAAmC;aACnB,YAAY,EAAE,QAAQ;IACtC,8CAA8C;aAC9B,eAAe,EAAE,SAAS;IAC1C,2DAA2D;aAC3C,OAAO,EAAE,aAAa;IACtC;;;;;OAKG;aACa,KAAK,EAAE,cAAc,CAAC,QAAQ,EAAE,cAAc,CAAC;IAxCjE,MAAM,CAAC,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAUT;IAEH,MAAM,CAAC,MAAM,CAAC,EACZ,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,OAAO,EACP,KAAK,GACN,EAAE,WAAW,CAAC,WAAW,CAAC;IAI3B,OAAO;CAqBR;AAED,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,OAAO,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"work-package.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/block/work-package.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,KAAK,WAAW,EAAS,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,EAAW,KAAK,EAAE,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAS,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,6EAA6E;AAC7E,0FAA0F;AAC1F,MAAM,MAAM,cAAc,GAAG,EAAE,CAAC;AAEhC,oDAAoD;AACpD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAM/D;AAED,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,IAAI,cAAc,CAEnE;AAED,kFAAkF;AAClF,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAC1C,uFAAuF;AACvF,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C;;;;;;GAMG;AACH,qBAAa,WAAY,SAAQ,SAAS;IAyBtC,wDAAwD;aACxC,aAAa,EAAE,SAAS;IACxC,kEAAkE;aAClD,YAAY,EAAE,SAAS;IACvC,mCAAmC;aACnB,YAAY,EAAE,QAAQ;IACtC,8CAA8C;aAC9B,eAAe,EAAE,SAAS;IAC1C,2DAA2D;aAC3C,OAAO,EAAE,aAAa;IACtC;;;;;OAKG;aACa,KAAK,EAAE,cAAc,CAAC,QAAQ,EAAE,cAAc,CAAC;IAxCjE,MAAM,CAAC,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAUT;IAEH,MAAM,CAAC,MAAM,CAAC,EACZ,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,OAAO,EACP,KAAK,GACN,EAAE,WAAW,CAAC,WAAW,CAAC;IAI3B,OAAO;CAqBR;AAED,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,OAAO,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC"}
@@ -5,14 +5,18 @@ import { tryAsU8 } from "#@typeberry/numbers";
5
5
  import { check, WithDebug } from "#@typeberry/utils";
6
6
  import { RefineContext } from "./refine-context.js";
7
7
  import { WorkItem } from "./work-item.js";
8
- /** Verify the value is within the `WorkItemsCount` bounds. */
8
+ /** Convert the value to `WorkItemsCount` bounds. */
9
9
  export function tryAsWorkItemsCount(len) {
10
10
  check `
11
- ${len >= MIN_NUMBER_OF_WORK_ITEMS && len <= MAX_NUMBER_OF_WORK_ITEMS}
11
+ ${isWorkItemsCount(len)}
12
12
  WorkItemsCount: Expected '${MIN_NUMBER_OF_WORK_ITEMS} <= count <= ${MAX_NUMBER_OF_WORK_ITEMS}' got ${len}
13
13
  `;
14
14
  return tryAsU8(len);
15
15
  }
16
+ /** Verify the value is within the `WorkItemsCount` bounds. */
17
+ export function isWorkItemsCount(len) {
18
+ return len >= MIN_NUMBER_OF_WORK_ITEMS && len <= MAX_NUMBER_OF_WORK_ITEMS;
19
+ }
16
20
  /** Minimal number of work items in the work package or results in work report. */
17
21
  export const MIN_NUMBER_OF_WORK_ITEMS = 1;
18
22
  /** `I`: Maximal number of work items in the work package or results in work report. */