@typeberry/lib 0.10.0 → 0.11.0-411c828

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 (161) hide show
  1. package/package.json +3 -5
  2. package/packages/configs/index.d.ts +9 -0
  3. package/packages/configs/index.d.ts.map +1 -1
  4. package/packages/configs/typeberry-default.json +4 -1
  5. package/packages/configs/typeberry-dev-full.json +3 -0
  6. package/packages/configs/typeberry-dev-tiny.json +3 -0
  7. package/packages/jam/config-node/index.d.ts +1 -0
  8. package/packages/jam/config-node/index.d.ts.map +1 -1
  9. package/packages/jam/config-node/index.js +1 -0
  10. package/packages/jam/config-node/node-config.d.ts +5 -11
  11. package/packages/jam/config-node/node-config.d.ts.map +1 -1
  12. package/packages/jam/config-node/node-config.js +9 -25
  13. package/packages/jam/config-node/node-config.test.js +11 -6
  14. package/packages/jam/config-node/rpc.d.ts +11 -0
  15. package/packages/jam/config-node/rpc.d.ts.map +1 -0
  16. package/packages/jam/config-node/rpc.js +16 -0
  17. package/packages/jam/database/states.d.ts +1 -8
  18. package/packages/jam/database/states.d.ts.map +1 -1
  19. package/packages/jam/database/value-refs.d.ts +4 -5
  20. package/packages/jam/database/value-refs.d.ts.map +1 -1
  21. package/packages/jam/database-fjall/blocks.d.ts +1 -0
  22. package/packages/jam/database-fjall/blocks.d.ts.map +1 -1
  23. package/packages/jam/database-fjall/blocks.js +8 -3
  24. package/packages/jam/database-fjall/hybrid-states.d.ts +10 -4
  25. package/packages/jam/database-fjall/hybrid-states.d.ts.map +1 -1
  26. package/packages/jam/database-fjall/hybrid-states.js +22 -6
  27. package/packages/jam/database-fjall/root.d.ts +2 -0
  28. package/packages/jam/database-fjall/root.d.ts.map +1 -1
  29. package/packages/jam/database-fjall/root.js +8 -1
  30. package/packages/jam/database-fjall/root.test.d.ts +2 -0
  31. package/packages/jam/database-fjall/root.test.d.ts.map +1 -0
  32. package/packages/jam/database-fjall/root.test.js +23 -0
  33. package/packages/jam/database-fjall/states.d.ts +1 -0
  34. package/packages/jam/database-fjall/states.d.ts.map +1 -1
  35. package/packages/jam/database-fjall/states.js +6 -3
  36. package/packages/jam/node/export.d.ts.map +1 -1
  37. package/packages/jam/node/export.js +8 -17
  38. package/packages/jam/node/jam-config.d.ts +5 -1
  39. package/packages/jam/node/jam-config.d.ts.map +1 -1
  40. package/packages/jam/node/jam-config.js +6 -2
  41. package/packages/jam/node/main-fuzz.d.ts.map +1 -1
  42. package/packages/jam/node/main-fuzz.js +59 -39
  43. package/packages/jam/node/main-importer.d.ts +6 -11
  44. package/packages/jam/node/main-importer.d.ts.map +1 -1
  45. package/packages/jam/node/main-importer.js +15 -29
  46. package/packages/jam/node/main.d.ts.map +1 -1
  47. package/packages/jam/node/main.js +6 -16
  48. package/packages/jam/rpc/index.d.ts +3 -0
  49. package/packages/jam/rpc/index.d.ts.map +1 -0
  50. package/packages/jam/rpc/index.js +2 -0
  51. package/packages/jam/rpc/src/handlers/best-block.d.ts +6 -0
  52. package/packages/jam/rpc/src/handlers/best-block.d.ts.map +1 -0
  53. package/packages/jam/rpc/src/handlers/best-block.js +15 -0
  54. package/packages/jam/rpc/src/handlers/finalized-block.d.ts +6 -0
  55. package/packages/jam/rpc/src/handlers/finalized-block.d.ts.map +1 -0
  56. package/packages/jam/rpc/src/handlers/finalized-block.js +7 -0
  57. package/packages/jam/rpc/src/handlers/list-services.d.ts +6 -0
  58. package/packages/jam/rpc/src/handlers/list-services.d.ts.map +1 -0
  59. package/packages/jam/rpc/src/handlers/list-services.js +15 -0
  60. package/packages/jam/rpc/src/handlers/not-implemented.d.ts +4 -0
  61. package/packages/jam/rpc/src/handlers/not-implemented.d.ts.map +1 -0
  62. package/packages/jam/rpc/src/handlers/not-implemented.js +4 -0
  63. package/packages/jam/rpc/src/handlers/parameters.d.ts +7 -0
  64. package/packages/jam/rpc/src/handlers/parameters.d.ts.map +1 -0
  65. package/packages/jam/rpc/src/handlers/parameters.js +53 -0
  66. package/packages/jam/rpc/src/handlers/parent.d.ts +6 -0
  67. package/packages/jam/rpc/src/handlers/parent.d.ts.map +1 -0
  68. package/packages/jam/rpc/src/handlers/parent.js +25 -0
  69. package/packages/jam/rpc/src/handlers/service-data.d.ts +6 -0
  70. package/packages/jam/rpc/src/handlers/service-data.d.ts.map +1 -0
  71. package/packages/jam/rpc/src/handlers/service-data.js +21 -0
  72. package/packages/jam/rpc/src/handlers/service-preimage.d.ts +6 -0
  73. package/packages/jam/rpc/src/handlers/service-preimage.d.ts.map +1 -0
  74. package/packages/jam/rpc/src/handlers/service-preimage.js +23 -0
  75. package/packages/jam/rpc/src/handlers/service-request.d.ts +6 -0
  76. package/packages/jam/rpc/src/handlers/service-request.d.ts.map +1 -0
  77. package/packages/jam/rpc/src/handlers/service-request.js +23 -0
  78. package/packages/jam/rpc/src/handlers/service-value.d.ts +6 -0
  79. package/packages/jam/rpc/src/handlers/service-value.d.ts.map +1 -0
  80. package/packages/jam/rpc/src/handlers/service-value.js +23 -0
  81. package/packages/jam/rpc/src/handlers/state-root.d.ts +6 -0
  82. package/packages/jam/rpc/src/handlers/state-root.d.ts.map +1 -0
  83. package/packages/jam/rpc/src/handlers/state-root.js +14 -0
  84. package/packages/jam/rpc/src/handlers/statistics.d.ts +6 -0
  85. package/packages/jam/rpc/src/handlers/statistics.d.ts.map +1 -0
  86. package/packages/jam/rpc/src/handlers/statistics.js +16 -0
  87. package/packages/jam/rpc/src/handlers/subscribe-best-block.d.ts +6 -0
  88. package/packages/jam/rpc/src/handlers/subscribe-best-block.d.ts.map +1 -0
  89. package/packages/jam/rpc/src/handlers/subscribe-best-block.js +8 -0
  90. package/packages/jam/rpc/src/handlers/subscribe-finalized-block.d.ts +6 -0
  91. package/packages/jam/rpc/src/handlers/subscribe-finalized-block.d.ts.map +1 -0
  92. package/packages/jam/rpc/src/handlers/subscribe-finalized-block.js +8 -0
  93. package/packages/jam/rpc/src/handlers/subscribe-service-data.d.ts +6 -0
  94. package/packages/jam/rpc/src/handlers/subscribe-service-data.d.ts.map +1 -0
  95. package/packages/jam/rpc/src/handlers/subscribe-service-data.js +13 -0
  96. package/packages/jam/rpc/src/handlers/subscribe-service-preimage.d.ts +6 -0
  97. package/packages/jam/rpc/src/handlers/subscribe-service-preimage.d.ts.map +1 -0
  98. package/packages/jam/rpc/src/handlers/subscribe-service-preimage.js +13 -0
  99. package/packages/jam/rpc/src/handlers/subscribe-service-request.d.ts +6 -0
  100. package/packages/jam/rpc/src/handlers/subscribe-service-request.d.ts.map +1 -0
  101. package/packages/jam/rpc/src/handlers/subscribe-service-request.js +13 -0
  102. package/packages/jam/rpc/src/handlers/subscribe-service-value.d.ts +6 -0
  103. package/packages/jam/rpc/src/handlers/subscribe-service-value.d.ts.map +1 -0
  104. package/packages/jam/rpc/src/handlers/subscribe-service-value.js +13 -0
  105. package/packages/jam/rpc/src/handlers/subscribe-statistics.d.ts +6 -0
  106. package/packages/jam/rpc/src/handlers/subscribe-statistics.d.ts.map +1 -0
  107. package/packages/jam/rpc/src/handlers/subscribe-statistics.js +13 -0
  108. package/packages/jam/rpc/src/handlers/typeberry/refine-work-package.d.ts +8 -0
  109. package/packages/jam/rpc/src/handlers/typeberry/refine-work-package.d.ts.map +1 -0
  110. package/packages/jam/rpc/src/handlers/typeberry/refine-work-package.js +68 -0
  111. package/packages/jam/rpc/src/handlers/unsubscribe.d.ts +4 -0
  112. package/packages/jam/rpc/src/handlers/unsubscribe.d.ts.map +1 -0
  113. package/packages/jam/rpc/src/handlers/unsubscribe.js +3 -0
  114. package/packages/jam/rpc/src/handlers.d.ts +3 -0
  115. package/packages/jam/rpc/src/handlers.d.ts.map +1 -0
  116. package/packages/jam/rpc/src/handlers.js +60 -0
  117. package/packages/jam/rpc/src/server.d.ts +31 -0
  118. package/packages/jam/rpc/src/server.d.ts.map +1 -0
  119. package/packages/jam/rpc/src/server.js +179 -0
  120. package/packages/jam/rpc/src/subscription-manager.d.ts +20 -0
  121. package/packages/jam/rpc/src/subscription-manager.d.ts.map +1 -0
  122. package/packages/jam/rpc/src/subscription-manager.js +74 -0
  123. package/packages/jam/rpc/test/e2e-server.d.ts +3 -0
  124. package/packages/jam/rpc/test/e2e-server.d.ts.map +1 -0
  125. package/packages/jam/rpc/test/e2e-server.js +30 -0
  126. package/packages/jam/rpc/test/e2e-setup.d.ts +2 -0
  127. package/packages/jam/rpc/test/e2e-setup.d.ts.map +1 -0
  128. package/packages/jam/rpc/test/e2e-setup.js +126 -0
  129. package/packages/jam/rpc/test/e2e.d.ts +2 -0
  130. package/packages/jam/rpc/test/e2e.d.ts.map +1 -0
  131. package/packages/jam/rpc/test/e2e.js +326 -0
  132. package/packages/jam/state-merkleization/index.d.ts +1 -1
  133. package/packages/jam/state-merkleization/index.js +1 -1
  134. package/packages/workers/api-node/config.d.ts +14 -46
  135. package/packages/workers/api-node/config.d.ts.map +1 -1
  136. package/packages/workers/api-node/config.js +31 -96
  137. package/packages/workers/api-node/config.test.js +82 -63
  138. package/packages/workers/importer/main.d.ts +2 -0
  139. package/packages/workers/importer/main.d.ts.map +1 -1
  140. package/packages/workers/importer/main.js +1 -1
  141. package/packages/jam/database-lmdb/blocks.d.ts +0 -24
  142. package/packages/jam/database-lmdb/blocks.d.ts.map +0 -1
  143. package/packages/jam/database-lmdb/blocks.js +0 -82
  144. package/packages/jam/database-lmdb/hybrid-states.d.ts +0 -56
  145. package/packages/jam/database-lmdb/hybrid-states.d.ts.map +0 -1
  146. package/packages/jam/database-lmdb/hybrid-states.js +0 -149
  147. package/packages/jam/database-lmdb/hybrid-states.test.d.ts +0 -2
  148. package/packages/jam/database-lmdb/hybrid-states.test.d.ts.map +0 -1
  149. package/packages/jam/database-lmdb/hybrid-states.test.js +0 -180
  150. package/packages/jam/database-lmdb/index.d.ts +0 -5
  151. package/packages/jam/database-lmdb/index.d.ts.map +0 -1
  152. package/packages/jam/database-lmdb/index.js +0 -4
  153. package/packages/jam/database-lmdb/root.d.ts +0 -26
  154. package/packages/jam/database-lmdb/root.d.ts.map +0 -1
  155. package/packages/jam/database-lmdb/root.js +0 -53
  156. package/packages/jam/database-lmdb/states.d.ts +0 -76
  157. package/packages/jam/database-lmdb/states.d.ts.map +0 -1
  158. package/packages/jam/database-lmdb/states.js +0 -145
  159. package/packages/jam/database-lmdb/states.test.d.ts +0 -2
  160. package/packages/jam/database-lmdb/states.test.d.ts.map +0 -1
  161. package/packages/jam/database-lmdb/states.test.js +0 -202
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=root.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"root.test.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/database-fjall/root.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,23 @@
1
+ import assert from "node:assert";
2
+ import * as fs from "node:fs";
3
+ import { describe, it } from "node:test";
4
+ import { FjallRoot } from "./root.js";
5
+ const key = Buffer.from("key");
6
+ const value = Buffer.from("value");
7
+ describe("FjallRoot", () => {
8
+ it("deletes a partition and recreates it empty", async () => {
9
+ const dbPath = fs.mkdtempSync("typeberry-fjall-root-");
10
+ const root = await FjallRoot.open(dbPath, { ephemeral: true });
11
+ try {
12
+ const first = await root.writablePartition("scratch");
13
+ await first.insert(key, value);
14
+ await root.deletePartition("scratch");
15
+ const second = await root.writablePartition("scratch");
16
+ assert.strictEqual(second.get(key), null);
17
+ }
18
+ finally {
19
+ await root.close();
20
+ fs.rmSync(dbPath, { recursive: true, force: true });
21
+ }
22
+ });
23
+ });
@@ -16,6 +16,7 @@ export declare class FjallStates implements StatesDb<SerializedState<LeafDb>>, I
16
16
  private readonly values;
17
17
  static open(spec: ChainSpec, blake2b: Blake2b, root: FjallRoot): Promise<FjallStates>;
18
18
  private readonly valuesDb;
19
+ private pendingPrune;
19
20
  private constructor();
20
21
  insertInitialState(headerHash: HeaderHash, entries: StateEntries): Promise<Result<OK, StateUpdateError>>;
21
22
  updateAndSetState(headerHash: HeaderHash, state: SerializedState<LeafDb>, update: Partial<State & ServicesUpdate>): Promise<Result<OK, StateUpdateError>>;
@@ -1 +1 @@
1
- {"version":3,"file":"states.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/database-fjall/states.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGlE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EACL,KAAK,YAAY,EACjB,MAAM,EACN,KAAK,QAAQ,EACb,gBAAgB,EAGjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,OAAO,EAAiB,MAAM,iBAAiB,CAAC;AAE9D,OAAO,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAY,MAAM,gCAAgC,CAAC;AAC7E,OAAO,EAAE,eAAe,EAAgD,MAAM,gCAAgC,CAAC;AAE/G,OAAO,EAAE,EAAE,EAAE,MAAM,EAAkB,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAuB,KAAK,SAAS,EAAgC,MAAM,WAAW,CAAC;AAI9F,0DAA0D;AAC1D,qBAAa,WAAY,YAAW,QAAQ,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,EAAE,YAAY,CAAC,YAAY,CAAC;IAS7F,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;WAZZ,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC;IAK3F,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IAEpC,OAAO;IAUD,kBAAkB,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,gBAAgB,CAAC,CAAC;IAQxG,iBAAiB,CACrB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,eAAe,CAAC,MAAM,CAAC,EAC9B,MAAM,EAAE,OAAO,CAAC,KAAK,GAAG,cAAc,CAAC,GACtC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,gBAAgB,CAAC,CAAC;IAUlC,YAAY,CAAC,KAAK,EAAE,eAAe,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC;IAI1E,QAAQ,CAAC,UAAU,EAAE,UAAU,GAAG,eAAe,CAAC,MAAM,CAAC,GAAG,IAAI;IAahE,eAAe,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI;IAK7C,UAAU,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI;IAMxC,eAAe,IAAI,MAAM,GAAG,IAAI;IAI1B,KAAK;YAEG,eAAe;IAyB7B,OAAO,CAAC,SAAS;CAOlB"}
1
+ {"version":3,"file":"states.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/database-fjall/states.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGlE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EACL,KAAK,YAAY,EACjB,MAAM,EACN,KAAK,QAAQ,EACb,gBAAgB,EAGjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,OAAO,EAAiB,MAAM,iBAAiB,CAAC;AAE9D,OAAO,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAY,MAAM,gCAAgC,CAAC;AAC7E,OAAO,EAAE,eAAe,EAAgD,MAAM,gCAAgC,CAAC;AAE/G,OAAO,EAAE,EAAE,EAAE,MAAM,EAAkB,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAuB,KAAK,SAAS,EAAgC,MAAM,WAAW,CAAC;AAI9F,0DAA0D;AAC1D,qBAAa,WAAY,YAAW,QAAQ,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,EAAE,YAAY,CAAC,YAAY,CAAC;IAU7F,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;WAbZ,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC;IAK3F,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IACpC,OAAO,CAAC,YAAY,CAAuC;IAE3D,OAAO;IAUD,kBAAkB,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,gBAAgB,CAAC,CAAC;IAQxG,iBAAiB,CACrB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,eAAe,CAAC,MAAM,CAAC,EAC9B,MAAM,EAAE,OAAO,CAAC,KAAK,GAAG,cAAc,CAAC,GACtC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,gBAAgB,CAAC,CAAC;IAUlC,YAAY,CAAC,KAAK,EAAE,eAAe,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC;IAI1E,QAAQ,CAAC,UAAU,EAAE,UAAU,GAAG,eAAe,CAAC,MAAM,CAAC,GAAG,IAAI;IAahE,eAAe,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI;IAK7C,UAAU,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI;IAMxC,eAAe,IAAI,MAAM,GAAG,IAAI;IAI1B,KAAK;YAIG,eAAe;IAyB7B,OAAO,CAAC,SAAS;CAOlB"}
@@ -19,6 +19,7 @@ export class FjallStates {
19
19
  return new FjallStates(spec, blake2b, root, states, values);
20
20
  }
21
21
  valuesDb;
22
+ pendingPrune = Promise.resolve();
22
23
  constructor(spec, blake2b, root, states, values) {
23
24
  this.spec = spec;
24
25
  this.blake2b = blake2b;
@@ -58,14 +59,16 @@ export class FjallStates {
58
59
  // would need counts persisted (and crash-consistent) alongside the values.
59
60
  }
60
61
  markUnused(headerHash) {
61
- void writable(this.states, this.root)
62
- .remove(headerHash.raw)
62
+ this.pendingPrune = this.pendingPrune
63
+ .then(() => writable(this.states, this.root).remove(headerHash.raw))
63
64
  .catch((e) => logger.warn `Failed to prune state ${headerHash}: ${e}`);
64
65
  }
65
66
  diskSizeInBytes() {
66
67
  return this.root.sizeInBytes();
67
68
  }
68
- async close() { }
69
+ async close() {
70
+ await this.pendingPrune;
71
+ }
69
72
  async updateAndCommit(headerHash, leafs, data) {
70
73
  const { values } = updateLeafs(leafs, this.blake2b, data);
71
74
  const stateLeafs = BytesBlob.blobFromParts(leafs.array.map((x) => x.node.raw));
@@ -1 +1 @@
1
- {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/node/export.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,wBAAsB,YAAY,CAAC,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,iBAoG9G"}
1
+ {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/node/export.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,wBAAsB,YAAY,CAAC,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,iBA2F9G"}
@@ -3,10 +3,9 @@ import path from "node:path";
3
3
  import { Block as BlockCodec } from "#@typeberry/block";
4
4
  import { Bytes } from "#@typeberry/bytes";
5
5
  import { Encoder } from "#@typeberry/codec";
6
- import { RegularStateBackend } from "#@typeberry/config-node";
7
6
  import { Blake2b, HASH_SIZE } from "#@typeberry/hash";
8
7
  import { Logger } from "#@typeberry/logger";
9
- import { FjallWorkerConfig, LmdbWorkerConfig } from "#@typeberry/workers-api-node";
8
+ import { FjallWorkerConfig } from "#@typeberry/workers-api-node";
10
9
  import { getChainSpec, getDatabasePath } from "./common.js";
11
10
  export async function exportBlocks(jamNodeConfig, output, withRelPath) {
12
11
  const logger = Logger.new(import.meta.filename, "export");
@@ -30,21 +29,13 @@ export async function exportBlocks(jamNodeConfig, output, withRelPath) {
30
29
  const blake2b = await Blake2b.createHasher();
31
30
  const chainSpec = getChainSpec(jamNodeConfig.node.flavor);
32
31
  const { dbPath } = getDatabasePath(blake2b, jamNodeConfig.nodeName, jamNodeConfig.node.chainSpec.genesisHeader, withRelPath(jamNodeConfig.node.databaseBasePath));
33
- const config = jamNodeConfig.node.stateBackend === RegularStateBackend.Fjall
34
- ? FjallWorkerConfig.new({
35
- nodeName: jamNodeConfig.nodeName,
36
- chainSpec,
37
- blake2b,
38
- dbPath,
39
- workerParams: undefined,
40
- })
41
- : LmdbWorkerConfig.new({
42
- nodeName: jamNodeConfig.nodeName,
43
- chainSpec,
44
- blake2b,
45
- dbPath,
46
- workerParams: undefined,
47
- });
32
+ const config = FjallWorkerConfig.new({
33
+ nodeName: jamNodeConfig.nodeName,
34
+ chainSpec,
35
+ blake2b,
36
+ dbPath,
37
+ workerParams: undefined,
38
+ });
48
39
  const rootDb = await config.openDatabase();
49
40
  const blocks = rootDb.getBlocksDb();
50
41
  logger.info `📖 Gathering blocks...`;
@@ -26,11 +26,13 @@ export declare class JamConfig {
26
26
  readonly dev: DevConfig | null;
27
27
  /** Networking options. */
28
28
  readonly network: NetworkConfig | null;
29
+ /** RPC WebSocket port. When set, an in-process RPC server is started. */
30
+ readonly rpcPort: number | null;
29
31
  /** Optional pre-genesis ancestry information. */
30
32
  readonly ancestry: [HeaderHash, TimeSlot][];
31
33
  /** Validator index for dev mode authorship. Use "all" to author as all validators. */
32
34
  readonly devValidatorIndex: U16 | "all" | null;
33
- static new({ isAuthoring, isFastForward, nodeName, nodeConfig, pvmBackend, devConfig, networkConfig, ancestry, devValidatorIndex, }: {
35
+ static new({ isAuthoring, isFastForward, nodeName, nodeConfig, pvmBackend, devConfig, networkConfig, rpcPort, ancestry, devValidatorIndex, }: {
34
36
  isAuthoring?: boolean;
35
37
  isFastForward?: boolean;
36
38
  nodeName: string;
@@ -38,6 +40,8 @@ export declare class JamConfig {
38
40
  pvmBackend: PvmBackend;
39
41
  devConfig?: DevConfig | null;
40
42
  networkConfig?: NetworkConfig | null;
43
+ /** RPC WebSocket port. When set, an in-process RPC server is started. */
44
+ rpcPort?: number | null;
41
45
  ancestry?: [HeaderHash, TimeSlot][];
42
46
  /** Validator index for dev mode authorship. Use "all" to author as all validators. */
43
47
  devValidatorIndex?: U16 | "all" | null;
@@ -1 +1 @@
1
- {"version":3,"file":"jam-config.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/node/jam-config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,UAAU,EACf,KAAK,QAAQ,EAGb,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,qCAAqC,CAAC;AACtF,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAE9C,eAAO,MAAM,kBAAkB;;;;CAI9B,CAAC;AAEF;;GAEG;AACH,qBAAa,SAAS;IAqClB,6CAA6C;aAC7B,WAAW,EAAE,OAAO;IACpC,6FAA6F;aAC7E,aAAa,EAAE,OAAO;IACtC,iBAAiB;aACD,QAAQ,EAAE,MAAM;IAChC,mCAAmC;aACnB,IAAI,EAAE,iBAAiB;IACvC,4BAA4B;aACZ,UAAU,EAAE,UAAU;IACtC,wCAAwC;aACxB,GAAG,EAAE,SAAS,GAAG,IAAI;IACrC,0BAA0B;aACV,OAAO,EAAE,aAAa,GAAG,IAAI;IAC7C,iDAAiD;aACjC,QAAQ,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE;IAClD,sFAAsF;aACtE,iBAAiB,EAAE,GAAG,GAAG,KAAK,GAAG,IAAI;IArDvD,MAAM,CAAC,GAAG,CAAC,EACT,WAAW,EACX,aAAa,EACb,QAAQ,EACR,UAAU,EACV,UAAU,EACV,SAAgB,EAChB,aAAoB,EACpB,QAAa,EACb,iBAAwB,GACzB,EAAE;QACD,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,iBAAiB,CAAC;QAC9B,UAAU,EAAE,UAAU,CAAC;QACvB,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;QAC7B,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;QACrC,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE,CAAC;QACpC,sFAAsF;QACtF,iBAAiB,CAAC,EAAE,GAAG,GAAG,KAAK,GAAG,IAAI,CAAC;KACxC;IAcD,OAAO;CAoBR;AAED,6CAA6C;AAC7C,MAAM,MAAM,aAAa,GAAG;IAC1B,uCAAuC;IACvC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,8BAA8B;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,kCAAkC;IAClC,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,oCAAoC;AACpC,MAAM,MAAM,SAAS,GAAG;IAGtB,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,QAAQ,EAAE,QAAQ,CAAC;IACnB,wCAAwC;IACxC,cAAc,EAAE,cAAc,CAAC;IAC/B,2CAA2C;IAC3C,IAAI,CAAC,EAAE,aAAa,CAAC;CACtB,CAAC;AAEF,gCAAgC;AAChC,MAAM,MAAM,aAAa,GAAG;IAC1B,2BAA2B;IAC3B,GAAG,EAAE,iBAAiB,CAAC;IACvB,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,SAAS,EAAE,QAAQ,EAAE,CAAC;CACvB,CAAC"}
1
+ {"version":3,"file":"jam-config.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/node/jam-config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,UAAU,EACf,KAAK,QAAQ,EAGb,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,qCAAqC,CAAC;AACtF,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAE9C,eAAO,MAAM,kBAAkB;;;;CAI9B,CAAC;AAEF;;GAEG;AACH,qBAAa,SAAS;IAyClB,6CAA6C;aAC7B,WAAW,EAAE,OAAO;IACpC,6FAA6F;aAC7E,aAAa,EAAE,OAAO;IACtC,iBAAiB;aACD,QAAQ,EAAE,MAAM;IAChC,mCAAmC;aACnB,IAAI,EAAE,iBAAiB;IACvC,4BAA4B;aACZ,UAAU,EAAE,UAAU;IACtC,wCAAwC;aACxB,GAAG,EAAE,SAAS,GAAG,IAAI;IACrC,0BAA0B;aACV,OAAO,EAAE,aAAa,GAAG,IAAI;IAC7C,yEAAyE;aACzD,OAAO,EAAE,MAAM,GAAG,IAAI;IACtC,iDAAiD;aACjC,QAAQ,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE;IAClD,sFAAsF;aACtE,iBAAiB,EAAE,GAAG,GAAG,KAAK,GAAG,IAAI;IA3DvD,MAAM,CAAC,GAAG,CAAC,EACT,WAAW,EACX,aAAa,EACb,QAAQ,EACR,UAAU,EACV,UAAU,EACV,SAAgB,EAChB,aAAoB,EACpB,OAAc,EACd,QAAa,EACb,iBAAwB,GACzB,EAAE;QACD,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,iBAAiB,CAAC;QAC9B,UAAU,EAAE,UAAU,CAAC;QACvB,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;QAC7B,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;QACrC,yEAAyE;QACzE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE,CAAC;QACpC,sFAAsF;QACtF,iBAAiB,CAAC,EAAE,GAAG,GAAG,KAAK,GAAG,IAAI,CAAC;KACxC;IAeD,OAAO;CAsBR;AAED,6CAA6C;AAC7C,MAAM,MAAM,aAAa,GAAG;IAC1B,uCAAuC;IACvC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,8BAA8B;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,kCAAkC;IAClC,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,oCAAoC;AACpC,MAAM,MAAM,SAAS,GAAG;IAGtB,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,QAAQ,EAAE,QAAQ,CAAC;IACnB,wCAAwC;IACxC,cAAc,EAAE,cAAc,CAAC;IAC/B,2CAA2C;IAC3C,IAAI,CAAC,EAAE,aAAa,CAAC;CACtB,CAAC;AAEF,gCAAgC;AAChC,MAAM,MAAM,aAAa,GAAG;IAC1B,2BAA2B;IAC3B,GAAG,EAAE,iBAAiB,CAAC;IACvB,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,SAAS,EAAE,QAAQ,EAAE,CAAC;CACvB,CAAC"}
@@ -15,10 +15,11 @@ export class JamConfig {
15
15
  pvmBackend;
16
16
  dev;
17
17
  network;
18
+ rpcPort;
18
19
  ancestry;
19
20
  devValidatorIndex;
20
- static new({ isAuthoring, isFastForward, nodeName, nodeConfig, pvmBackend, devConfig = null, networkConfig = null, ancestry = [], devValidatorIndex = null, }) {
21
- return new JamConfig(isAuthoring ?? false, isFastForward ?? false, nodeName, nodeConfig, pvmBackend, devConfig, networkConfig, ancestry, devValidatorIndex);
21
+ static new({ isAuthoring, isFastForward, nodeName, nodeConfig, pvmBackend, devConfig = null, networkConfig = null, rpcPort = null, ancestry = [], devValidatorIndex = null, }) {
22
+ return new JamConfig(isAuthoring ?? false, isFastForward ?? false, nodeName, nodeConfig, pvmBackend, devConfig, networkConfig, rpcPort, ancestry, devValidatorIndex);
22
23
  }
23
24
  constructor(
24
25
  /** Whether we should be authoring blocks. */
@@ -35,6 +36,8 @@ export class JamConfig {
35
36
  dev,
36
37
  /** Networking options. */
37
38
  network,
39
+ /** RPC WebSocket port. When set, an in-process RPC server is started. */
40
+ rpcPort,
38
41
  /** Optional pre-genesis ancestry information. */
39
42
  ancestry,
40
43
  /** Validator index for dev mode authorship. Use "all" to author as all validators. */
@@ -46,6 +49,7 @@ export class JamConfig {
46
49
  this.pvmBackend = pvmBackend;
47
50
  this.dev = dev;
48
51
  this.network = network;
52
+ this.rpcPort = rpcPort;
49
53
  this.ancestry = ancestry;
50
54
  this.devValidatorIndex = devValidatorIndex;
51
55
  }
@@ -1 +1 @@
1
- {"version":3,"file":"main-fuzz.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/node/main-fuzz.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,WAAW,EAAmB,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAIrD,OAAO,EAAE,KAAK,MAAM,EAAoC,MAAM,kBAAkB,CAAC;AAGjF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIjD,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,WAAW,CAAC;IACrB,aAAa,EAAE,SAAS,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,uBAAuB,EAAE,OAAO,CAAC;CAClC,CAAC;AAoBF;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CASpF;AAED,iFAAiF;AACjF,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5D;AAED,wBAAgB,cAAc;;;;EAM7B;AAED,wBAAsB,QAAQ,CAAC,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAgLrH"}
1
+ {"version":3,"file":"main-fuzz.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/node/main-fuzz.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,WAAW,EAAmB,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAIrD,OAAO,EAAE,KAAK,MAAM,EAAoC,MAAM,kBAAkB,CAAC;AAGjF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIjD,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,WAAW,CAAC;IACrB,aAAa,EAAE,SAAS,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,uBAAuB,EAAE,OAAO,CAAC;CAClC,CAAC;AAoBF;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CASpF;AAED,iFAAiF;AACjF,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5D;AAED,wBAAgB,cAAc;;;;EAM7B;AAED,wBAAsB,QAAQ,CAAC,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAmMrH"}
@@ -8,23 +8,23 @@ import { v1 as fuzzV1 } from "#@typeberry/fuzz-proto";
8
8
  import { HASH_SIZE } from "#@typeberry/hash";
9
9
  import { Logger } from "#@typeberry/logger";
10
10
  import { CURRENT_VERSION, Result, version } from "#@typeberry/utils";
11
- import { FjallValuesSession, logHostEnvironment } from "#@typeberry/workers-api-node";
11
+ import { FjallRoot, logHostEnvironment } from "#@typeberry/workers-api-node";
12
12
  import { getChainSpec } from "./common.js";
13
13
  import { mainImporter } from "./main-importer.js";
14
14
  const logger = Logger.new(import.meta.filename, "fuzztarget");
15
15
  /** Dedicated subdirectory under the configured base path that the fuzzer owns and wipes. */
16
16
  const FUZZ_DB_SUBDIR = "typeberry-fuzz-db";
17
17
  const FUZZ_DB_FJALL = "fjall-hybrid";
18
- const FUZZ_DB_LMDB = "lmdb-hybrid";
19
- const FUZZ_DB_OPTIONS = [FUZZ_DB_FJALL, FUZZ_DB_LMDB];
20
- /** Subdirectory (under the fuzzer's db dir) holding the reused fjall values keyspace. */
21
- const FUZZ_FJALL_VALUES_SUBDIR = "values-session";
18
+ const FUZZ_DB_OPTIONS = [FUZZ_DB_FJALL, "fjall"];
19
+ /** The partitions used by FjallBlocks and FjallStates in the full-fjall backend. */
20
+ const FUZZ_FJALL_PARTITIONS = ["headers", "extrinsics", "postStateRoots", "states", "values"];
22
21
  /**
23
- * Size of the fjall block-cache for the fuzz session. Values pile up across
24
- * resets (for fjall we do not wipe between them), so this cache is what keeps
25
- * the resident memory bounded.
22
+ * Size of the fjall block-cache for the fuzz session. The keyspace stays open
23
+ * across resets, so this cache is what keeps the resident memory bounded.
26
24
  */
27
25
  const FUZZ_FJALL_CACHE_BYTES = 128 * 1024 * 1024;
26
+ /** Rebuild the fjall-hybrid keyspace every N resets to limit LSM read amplification. */
27
+ const REBUILD_FJALL_HYBRID_KEYSPACE_EVERY = 50;
28
28
  /**
29
29
  * Resolve the directory the fuzzer should use for its on-disk database, or
30
30
  * `undefined` for an in-memory database. The dedicated `FUZZ_DB_SUBDIR` is
@@ -62,7 +62,6 @@ export async function mainFuzz(fuzzConfig, withRelPath) {
62
62
  const { jamNodeConfig: config } = fuzzConfig;
63
63
  const fuzzDbBase = resolveFuzzDbBase(config.node.databaseBasePath);
64
64
  const rawFuzzDb = process.env.JAM_FUZZ_DB?.trim() ?? "";
65
- // Using experimental fjall-hybrid by default, with an option to test lmdb as well.
66
65
  const hybridStateBackend = rawFuzzDb === "" ? FUZZ_DB_FJALL : rawFuzzDb;
67
66
  if (!isValidStateBackend(hybridStateBackend)) {
68
67
  throw new Error(`JAM_FUZZ_DB must be one of: ${FUZZ_DB_OPTIONS} (got: "${rawFuzzDb}").`);
@@ -71,10 +70,11 @@ export async function mainFuzz(fuzzConfig, withRelPath) {
71
70
  logger.info `🗄️ Fuzz persistent backend: ${hybridStateBackend}.`;
72
71
  }
73
72
  let runningNode = null;
74
- // The fjall values keyspace is opened once per fuzz session and reused on
75
- // every reset, because opening it is the slow part. Only the in-memory blocks
76
- // and leaf sets are rebuilt for each vector. fjall-hybrid only.
77
- let fjallSession = null;
73
+ // The fjall keyspace is opened once per fuzz session and reused on every
74
+ // reset, because opening it is the slow part.
75
+ let fjallKeyspace = null;
76
+ // Track how many times resetState has been called for periodic fjall keyspace rebuilds.
77
+ let resetCount = 0;
78
78
  // Set when close() starts. Guards resetState so a fuzz command arriving
79
79
  // mid-shutdown can't build a fresh node that close() then orphans.
80
80
  let isClosing = false;
@@ -112,6 +112,8 @@ export async function mainFuzz(fuzzConfig, withRelPath) {
112
112
  runningNode = null;
113
113
  await finish;
114
114
  }
115
+ // Increment reset counter for periodic fjall session rebuilds.
116
+ resetCount++;
115
117
  const buildNode = (databaseBasePath) => {
116
118
  const isPersistent = databaseBasePath !== undefined;
117
119
  return mainImporter({
@@ -138,37 +140,55 @@ export async function mainFuzz(fuzzConfig, withRelPath) {
138
140
  // also turns on compression further down, so the big values do not grow the
139
141
  // db too much. Tiny stays uncompressed, its db is small and speed matters more.
140
142
  ephemeral: isPersistent,
141
- stateBackend: isPersistent ? hybridStateBackend : "lmdb",
142
- // Reuse the session keyspace (fjall-hybrid only, other backends
143
- // ignore it). Nothing to pass for the in-memory fallback.
144
- sharedFjallSession: isPersistent ? (fjallSession ?? undefined) : undefined,
143
+ stateBackend: isPersistent ? hybridStateBackend : "fjall",
144
+ // Reuse the keyspace for both fjall backends. Nothing to pass for
145
+ // the in-memory fallback.
146
+ sharedFjallKeyspace: fjallKeyspace ?? undefined,
145
147
  });
146
148
  };
147
149
  if (fuzzDbBase !== undefined) {
148
150
  try {
151
+ const fjallKeyspacePath = withRelPath(fuzzDbBase);
149
152
  if (hybridStateBackend === FUZZ_DB_FJALL) {
150
- // fjall-hybrid: open the values keyspace once and reuse it on every
151
- // reset. The values partition is content-addressed and immutable, so
152
- // it is fine that values pile up across resets, the unreferenced ones
153
- // just sit there. `initializeDatabase` decides whether the db is
154
- // already initialized from the in-memory blocks, which we rebuild on
155
- // every reset, not from the values store, so reusing it does not
156
- // resume the previous run.
157
- if (fjallSession === null) {
158
- // Start from a clean slate once, then keep the keyspace open.
153
+ // fjall-hybrid: values pile up across resets, so rebuild the
154
+ // keyspace periodically to avoid LSM read amplification.
155
+ if (resetCount === 1 || fjallKeyspace === null) {
156
+ // First reset: start from a clean slate.
159
157
  await wipeFuzzDb(fuzzDbBase);
160
- fjallSession = await FjallValuesSession.open(`${withRelPath(fuzzDbBase)}/${FUZZ_FJALL_VALUES_SUBDIR}`, {
158
+ fjallKeyspace = await FjallRoot.open(fjallKeyspacePath, {
161
159
  ephemeral: true,
162
160
  cacheSizeBytes: FUZZ_FJALL_CACHE_BYTES,
163
161
  });
164
- logger.info `🗄️ Opened reusable fjall values session at ${withRelPath(fuzzDbBase)}/${FUZZ_FJALL_VALUES_SUBDIR}`;
162
+ logger.info `🗄️ Opened reusable fjall keyspace at ${fjallKeyspacePath}`;
163
+ }
164
+ else if (resetCount % REBUILD_FJALL_HYBRID_KEYSPACE_EVERY === 0) {
165
+ // Periodic rebuild: close, wipe keyspace dir, and reopen.
166
+ const keyspace = fjallKeyspace;
167
+ fjallKeyspace = null;
168
+ await keyspace.close().catch(() => { });
169
+ await wipeFuzzDb(fuzzDbBase).catch(() => { });
170
+ fjallKeyspace = await FjallRoot.open(fjallKeyspacePath, {
171
+ ephemeral: true,
172
+ cacheSizeBytes: FUZZ_FJALL_CACHE_BYTES,
173
+ });
174
+ logger.info `🗄️ Rebuilt reusable fjall keyspace at ${fjallKeyspacePath}`;
165
175
  }
166
176
  }
167
177
  else {
168
- // lmdb-hybrid: keep the old behaviour, wipe and reopen on every
169
- // reset. A fresh db each reset makes `initializeDatabase` set up
170
- // genesis again instead of resuming the previous run.
171
- await wipeFuzzDb(fuzzDbBase);
178
+ // full-fjall: keep one keyspace open and recycle only the five
179
+ // partitions used by FjallBlocks/FjallStates.
180
+ if (resetCount === 1 || fjallKeyspace === null) {
181
+ await wipeFuzzDb(fuzzDbBase);
182
+ fjallKeyspace = await FjallRoot.open(fjallKeyspacePath, {
183
+ ephemeral: true,
184
+ cacheSizeBytes: FUZZ_FJALL_CACHE_BYTES,
185
+ });
186
+ logger.info `🗄️ Opened reusable fjall keyspace at ${fjallKeyspacePath}`;
187
+ }
188
+ else if (fjallKeyspace !== null) {
189
+ const keyspace = fjallKeyspace;
190
+ await Promise.all(FUZZ_FJALL_PARTITIONS.map((name) => keyspace.deletePartition(name)));
191
+ }
172
192
  }
173
193
  runningNode = await buildNode(fuzzDbBase);
174
194
  return await runningNode.getBestStateRootHash();
@@ -197,9 +217,9 @@ export async function mainFuzz(fuzzConfig, withRelPath) {
197
217
  isClosing = true;
198
218
  // Stop accepting connections + unlink the socket.
199
219
  closeFuzzTarget();
200
- // Drain the active session (flush + close DB). Swallow errors so a
220
+ // Drain the active reset (flush + close DB). Swallow errors so a
201
221
  // failing close still lets the process exit 0; the db is wiped next.
202
- // The node references the shared fjall session, so it must close first.
222
+ // The node references the shared fjall keyspace, so it must close first.
203
223
  if (activeReset !== null) {
204
224
  await activeReset.catch((e) => logger.error `Error waiting for fuzz reset: ${e}`);
205
225
  }
@@ -208,11 +228,11 @@ export async function mainFuzz(fuzzConfig, withRelPath) {
208
228
  runningNode = null;
209
229
  await node.close().catch((e) => logger.error `Error closing fuzz node: ${e}`);
210
230
  }
211
- // Release the reused fjall values keyspace before wiping its files.
212
- if (fjallSession !== null) {
213
- const session = fjallSession;
214
- fjallSession = null;
215
- await session.close().catch((e) => logger.error `Error closing fjall session: ${e}`);
231
+ // Release the reused fjall keyspace before wiping its files.
232
+ if (fjallKeyspace !== null) {
233
+ const keyspace = fjallKeyspace;
234
+ fjallKeyspace = null;
235
+ await keyspace.close().catch((e) => logger.error `Error closing fjall keyspace: ${e}`);
216
236
  }
217
237
  if (fuzzDbBase !== undefined) {
218
238
  await wipeFuzzDb(fuzzDbBase).catch(() => { });
@@ -1,25 +1,20 @@
1
- import { type FjallValuesSession } from "#@typeberry/workers-api-node";
1
+ import { type FjallRoot } from "#@typeberry/workers-api-node";
2
2
  import type { JamConfig } from "./jam-config.js";
3
3
  import type { NodeApi } from "./main.js";
4
- export type StateBackend = "lmdb" | "fjall" | "lmdb-hybrid" | "fjall-hybrid";
4
+ export type StateBackend = "fjall" | "fjall-hybrid";
5
5
  export type ImporterOptions = {
6
6
  initGenesisFromAncestry?: boolean;
7
7
  dummyFinalityDepth?: number;
8
8
  pruneBlocks?: boolean;
9
9
  /** Open the database without fsync/compression. Only safe for throwaway dbs (e.g. fuzzing). */
10
10
  ephemeral?: boolean;
11
- /**
12
- * Persistent backend used when `databaseBasePath` is set. Defaults to config's backend (fjall unless overridden).
13
- *
14
- * lmdb and lmdb-hybrid are deprecated and retained as explicit fallbacks.
15
- */
11
+ /** Persistent backend used when `databaseBasePath` is set. Defaults to fjall. */
16
12
  stateBackend?: StateBackend;
17
13
  /**
18
- * Reuse an already-open fjall values session instead of opening a fresh
19
- * keyspace. Only used when `stateBackend === "fjall-hybrid"`. The fuzz target
20
- * opens one per run and reuses it across resets.
14
+ * Reuse an already-open fjall keyspace instead of opening a fresh keyspace
15
+ * from `dbPath`. Used by fjall and fjall-hybrid fuzz targets.
21
16
  */
22
- sharedFjallSession?: FjallValuesSession;
17
+ sharedFjallKeyspace?: FjallRoot;
23
18
  };
24
19
  export declare function mainImporter(config: JamConfig, withRelPath: (v: string) => string, options?: ImporterOptions): Promise<NodeApi>;
25
20
  //# sourceMappingURL=main-importer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"main-importer.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/node/main-importer.ts"],"names":[],"mappings":"AASA,OAAO,EACL,KAAK,kBAAkB,EAKxB,MAAM,6BAA6B,CAAC;AAErC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,aAAa,GAAG,cAAc,CAAC;AAE7E,MAAM,MAAM,eAAe,GAAG;IAC5B,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,+FAA+F;IAC/F,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CACzC,CAAC;AAEF,wBAAsB,YAAY,CAChC,MAAM,EAAE,SAAS,EACjB,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,EAClC,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,OAAO,CAAC,CAqHlB"}
1
+ {"version":3,"file":"main-importer.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/node/main-importer.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,SAAS,EAA4D,MAAM,6BAA6B,CAAC;AAEvH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,cAAc,CAAC;AAEpD,MAAM,MAAM,eAAe,GAAG;IAC5B,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,+FAA+F;IAC/F,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iFAAiF;IACjF,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;;OAGG;IACH,mBAAmB,CAAC,EAAE,SAAS,CAAC;CACjC,CAAC;AAEF,wBAAsB,YAAY,CAChC,MAAM,EAAE,SAAS,EACjB,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,EAClC,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,OAAO,CAAC,CAqGlB"}
@@ -1,12 +1,12 @@
1
1
  import { Bytes } from "#@typeberry/bytes";
2
2
  import { PvmBackend } from "#@typeberry/config";
3
- import { KnownChainSpec, RegularStateBackend } from "#@typeberry/config-node";
3
+ import { KnownChainSpec } from "#@typeberry/config-node";
4
4
  import { bandersnatch, initWasm } from "#@typeberry/crypto";
5
5
  import { Blake2b, HASH_SIZE } from "#@typeberry/hash";
6
6
  import { createImporter, ImporterConfig } from "#@typeberry/importer";
7
7
  import { tryAsU16 } from "#@typeberry/numbers";
8
8
  import { CURRENT_SUITE, CURRENT_VERSION, Result, resultToString, version } from "#@typeberry/utils";
9
- import { FjallWorkerConfig, HybridWorkerConfig, InMemWorkerConfig, LmdbWorkerConfig, } from "#@typeberry/workers-api-node";
9
+ import { FjallWorkerConfig, HybridWorkerConfig, InMemWorkerConfig } from "#@typeberry/workers-api-node";
10
10
  import { getChainSpec, getDatabasePath, initializeDatabase, logger } from "./common.js";
11
11
  const zeroHash = Bytes.zero(HASH_SIZE).asOpaque();
12
12
  export async function mainImporter(config, withRelPath, options = {}) {
@@ -18,13 +18,8 @@ export async function mainImporter(config, withRelPath, options = {}) {
18
18
  logger.info `🐇 Bandersnatch ${bandesnatchNative.isOk ? "native 🚀" : `using wasm: ${bandesnatchNative.error}`}`;
19
19
  // Single source of truth for the states db backend: drives both the log line
20
20
  // below and the worker config picked further down.
21
- const dbBackend = config.node.databaseBasePath === undefined
22
- ? "in-memory"
23
- : (options.stateBackend ?? config.node.stateBackend ?? RegularStateBackend.Fjall);
21
+ const dbBackend = config.node.databaseBasePath === undefined ? "in-memory" : (options.stateBackend ?? "fjall");
24
22
  logger.info `🗄️ States DB: ${dbBackend}.`;
25
- if (dbBackend === "lmdb" || dbBackend === "lmdb-hybrid") {
26
- logger.warn `🗄️ The ${dbBackend} state backend is deprecated. Use fjall unless you need a temporary fallback.`;
27
- }
28
23
  const chainSpec = getChainSpec(config.node.flavor);
29
24
  const blake2b = await Blake2b.createHasher();
30
25
  const nodeName = config.nodeName;
@@ -44,7 +39,7 @@ export async function mainImporter(config, withRelPath, options = {}) {
44
39
  blake2b,
45
40
  workerParams,
46
41
  })
47
- : dbBackend === "lmdb-hybrid" || dbBackend === "fjall-hybrid"
42
+ : dbBackend === "fjall-hybrid"
48
43
  ? await HybridWorkerConfig.new({
49
44
  nodeName,
50
45
  chainSpec,
@@ -53,35 +48,26 @@ export async function mainImporter(config, withRelPath, options = {}) {
53
48
  workerParams,
54
49
  ephemeral,
55
50
  compression,
56
- backend: dbBackend === "lmdb-hybrid" ? "lmdb" : "fjall",
57
- sharedFjallSession: options.sharedFjallSession,
51
+ sharedFjallKeyspace: options.sharedFjallKeyspace,
58
52
  })
59
- : dbBackend === "fjall"
60
- ? FjallWorkerConfig.new({
61
- nodeName,
62
- chainSpec,
63
- blake2b,
64
- dbPath,
65
- workerParams,
66
- ephemeral,
67
- })
68
- : LmdbWorkerConfig.new({
69
- nodeName,
70
- chainSpec,
71
- blake2b,
72
- dbPath,
73
- workerParams,
74
- ephemeral,
75
- });
53
+ : FjallWorkerConfig.new({
54
+ nodeName,
55
+ chainSpec,
56
+ blake2b,
57
+ dbPath,
58
+ workerParams,
59
+ ephemeral,
60
+ sharedFjallKeyspace: options.sharedFjallKeyspace,
61
+ });
76
62
  // Initialize the database with genesis state and block if there isn't one.
77
63
  logger.info `🛢️ Opening database at ${dbPath}`;
78
64
  const rootDb = await workerConfig.openDatabase({ readonly: false });
79
65
  await initializeDatabase(chainSpec, blake2b, genesisHeaderHash, rootDb, config.node.chainSpec, config.ancestry, {
80
66
  initGenesisFromAncestry: options.initGenesisFromAncestry,
81
67
  });
82
- await rootDb.close();
83
68
  const { db, importer } = await createImporter(workerConfig, {
84
69
  initGenesisFromAncestry: options.initGenesisFromAncestry,
70
+ db: rootDb,
85
71
  });
86
72
  await importer.prepareForNextEpoch();
87
73
  const api = {
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/node/main.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAc,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEzF,OAAO,EAAE,KAAK,SAAS,EAAc,MAAM,mBAAmB,CAAC;AAgB/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAkC,MAAM,EAAW,MAAM,kBAAkB,CAAC;AAYnF,OAAO,KAAK,EAAE,SAAS,EAAiB,MAAM,iBAAiB,CAAC;AAWhE,MAAM,MAAM,OAAO,GAAG;IACpB,SAAS,EAAE,SAAS,CAAC;IACrB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAChE,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;IACtE,oBAAoB,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IAC/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,CAAC;AAEF,wBAAsB,IAAI,CACxB,MAAM,EAAE,SAAS,EACjB,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,EAClC,SAAS,EAAE,SAAS,GAAG,IAAI,GAC1B,OAAO,CAAC,OAAO,CAAC,CA2LlB"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/node/main.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAc,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEzF,OAAO,EAAE,KAAK,SAAS,EAAc,MAAM,mBAAmB,CAAC;AAe/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAkC,MAAM,EAAW,MAAM,kBAAkB,CAAC;AAWnF,OAAO,KAAK,EAAE,SAAS,EAAiB,MAAM,iBAAiB,CAAC;AAWhE,MAAM,MAAM,OAAO,GAAG;IACpB,SAAS,EAAE,SAAS,CAAC;IACrB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAChE,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;IACtE,oBAAoB,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IAC/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,CAAC;AAEF,wBAAsB,IAAI,CACxB,MAAM,EAAE,SAAS,EACjB,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,EAClC,SAAS,EAAE,SAAS,GAAG,IAAI,GAC1B,OAAO,CAAC,OAAO,CAAC,CAuLlB"}
@@ -1,7 +1,6 @@
1
1
  import { isMainThread } from "node:worker_threads";
2
2
  import { AUTHORSHIP_NETWORK_PORT } from "#@typeberry/comms-authorship-network";
3
3
  import { PvmBackend } from "#@typeberry/config";
4
- import { RegularStateBackend } from "#@typeberry/config-node";
5
4
  import { initWasm } from "#@typeberry/crypto";
6
5
  import { deriveBandersnatchSecretKey, deriveEd25519SecretKey, trivialSeed, } from "#@typeberry/crypto/key-derivation.js";
7
6
  import { Blake2b } from "#@typeberry/hash";
@@ -11,7 +10,7 @@ import { Listener } from "#@typeberry/listener";
11
10
  import { tryAsU16, tryAsU32 } from "#@typeberry/numbers";
12
11
  import { CURRENT_SUITE, CURRENT_VERSION, Result, version } from "#@typeberry/utils";
13
12
  import { DirectPort, DirectWorkerConfig } from "#@typeberry/workers-api";
14
- import { FjallWorkerConfig, InMemWorkerConfig, LmdbWorkerConfig, logHostEnvironment, ThreadPort, } from "#@typeberry/workers-api-node";
13
+ import { FjallWorkerConfig, InMemWorkerConfig, logHostEnvironment, ThreadPort, } from "#@typeberry/workers-api-node";
15
14
  import { getChainSpec, getDatabasePath, initializeDatabase, logger } from "./common.js";
16
15
  import { initializeExtensions } from "./extensions.js";
17
16
  import * as metrics from "./metrics.js";
@@ -30,12 +29,9 @@ export async function main(config, withRelPath, telemetry) {
30
29
  const blake2b = await Blake2b.createHasher();
31
30
  const nodeName = config.nodeName;
32
31
  const isInMemory = config.node.databaseBasePath === undefined;
33
- logger.info `🗄️ States DB: ${isInMemory ? "in-memory" : config.node.stateBackend}.`;
34
- if (!isInMemory && config.node.stateBackend === RegularStateBackend.Lmdb) {
35
- logger.warn `🗄️ The lmdb state backend is deprecated. Use state_backend="fjall" unless you need a temporary fallback.`;
36
- }
32
+ logger.info `🗄️ States DB: ${isInMemory ? "in-memory" : "fjall"}.`;
37
33
  const { dbPath, genesisHeaderHash } = getDatabasePath(blake2b, nodeName, config.node.chainSpec.genesisHeader, withRelPath(config.node.databaseBasePath ?? "<in-memory>"));
38
- const baseConfig = { nodeName, chainSpec, blake2b, dbPath, stateBackend: config.node.stateBackend };
34
+ const baseConfig = { nodeName, chainSpec, blake2b, dbPath };
39
35
  const importerParams = {
40
36
  ...baseConfig,
41
37
  workerParams: ImporterConfig.create({
@@ -63,9 +59,8 @@ export async function main(config, withRelPath, telemetry) {
63
59
  throw e;
64
60
  }
65
61
  // fjall-js shares the engine explicitly and requires every handle to close.
66
- // Keep lmdb's historical main-thread handle open until shutdown.
67
62
  let mainRootDb = rootDb;
68
- if (!importerConfig.isInMemory && config.node.stateBackend === RegularStateBackend.Fjall) {
63
+ if (!importerConfig.isInMemory) {
69
64
  await rootDb.close();
70
65
  mainRootDb = null;
71
66
  }
@@ -241,11 +236,6 @@ const initNetwork = async (importer, params, baseConfig, genesisHeaderHash, netw
241
236
  });
242
237
  return { closeNetwork: finish, networkApi: network, networkWorker: worker };
243
238
  };
244
- function createPersistentWorkerConfig({ stateBackend, ...params }) {
245
- switch (stateBackend) {
246
- case RegularStateBackend.Fjall:
247
- return FjallWorkerConfig.new(params);
248
- case RegularStateBackend.Lmdb:
249
- return LmdbWorkerConfig.new(params);
250
- }
239
+ function createPersistentWorkerConfig(params) {
240
+ return FjallWorkerConfig.new(params);
251
241
  }
@@ -0,0 +1,3 @@
1
+ export { handlers as rpcHandlers } from "./src/handlers.js";
2
+ export { RpcServer } from "./src/server.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/rpc/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { handlers as rpcHandlers } from "./src/handlers.js";
2
+ export { RpcServer } from "./src/server.js";
@@ -0,0 +1,6 @@
1
+ import { type Handler } from "#@typeberry/rpc-validation";
2
+ /**
3
+ * https://github.com/polkadot-fellows/JIPs/blob/772ce90bfc33f4e1de9de3bbe10c561753cc0d41/JIP-2.md#bestblock
4
+ */
5
+ export declare const bestBlock: Handler<"bestBlock">;
6
+ //# sourceMappingURL=best-block.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"best-block.d.ts","sourceRoot":"","sources":["../../../../../../../packages/jam/rpc/src/handlers/best-block.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAsC,MAAM,2BAA2B,CAAC;AAE7F;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,OAAO,CAAC,WAAW,CAgB1C,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { RpcError, RpcErrorCode, validation } from "#@typeberry/rpc-validation";
2
+ /**
3
+ * https://github.com/polkadot-fellows/JIPs/blob/772ce90bfc33f4e1de9de3bbe10c561753cc0d41/JIP-2.md#bestblock
4
+ */
5
+ export const bestBlock = async (_params, { db }) => {
6
+ const headerHash = db.blocks.getBestHeaderHash();
7
+ const header = db.blocks.getHeader(headerHash);
8
+ if (header === null) {
9
+ throw new RpcError(RpcErrorCode.BlockUnavailable, `Best header not found with hash: ${headerHash.toString()}`, validation.hash.encode(headerHash.raw));
10
+ }
11
+ return {
12
+ header_hash: headerHash.raw,
13
+ slot: header.timeSlotIndex.materialize(),
14
+ };
15
+ };
@@ -0,0 +1,6 @@
1
+ import type { Handler } from "#@typeberry/rpc-validation";
2
+ /**
3
+ * https://github.com/polkadot-fellows/JIPs/blob/772ce90bfc33f4e1de9de3bbe10c561753cc0d41/JIP-2.md#finalizedblock
4
+ */
5
+ export declare const finalizedBlock: Handler<"finalizedBlock">;
6
+ //# sourceMappingURL=finalized-block.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finalized-block.d.ts","sourceRoot":"","sources":["../../../../../../../packages/jam/rpc/src/handlers/finalized-block.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAGzD;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,OAAO,CAAC,gBAAgB,CAEpD,CAAC"}